Pull up following revision(s) (requested by msaitoh in ticket #833): usr.sbin/cpuctl/arch/i386.c: revision 1.109 sys/arch/x86/include/specialreg.h: revision 1.159 usr.sbin/cpuctl/arch/i386.c: revision 1.110 sys/arch/x86/include/specialreg.h: revision 1.160 sys/arch/x86/include/specialreg.h: revision 1.161 sys/arch/x86/x86/tsc.c: revision 1.40 sys/arch/x86/x86/procfs_machdep.c: revision 1.35 sys/arch/x86/x86/procfs_machdep.c: revision 1.36 Add Fast Short Rep Mov(fsrm). Add AVX512_VP2INTERSECT, SERIALIZE and TSXLDTRK(TSX suspend load addr tracking) CPUID Fn00000001 %edx bit 8 is printed as "TSC", so rename CPUID Fn8000_0007 %edx bit 8 from "TSC" to "ITSC" (Invariant TSC) to avoid confusion. Rename CPUID_APM_TSC to CPUID_APM_ITSC. No functional change. Remove ci_max_ext_cpuid because it's the same as ci_cpuid_extlevel. Print CPUID 0x80000007 %edx on both Intel and AMD.diff -r1.150.2.5 -r1.150.2.6 src/sys/arch/x86/include/specialreg.h
(martin)
--- src/sys/arch/x86/include/specialreg.h 2019/11/19 13:15:57 1.150.2.5
+++ src/sys/arch/x86/include/specialreg.h 2020/04/14 17:15:02 1.150.2.6
@@ -1,1156 +1,1162 @@ | @@ -1,1156 +1,1162 @@ | |||
1 | /* $NetBSD: specialreg.h,v 1.150.2.5 2019/11/19 13:15:57 martin Exp $ */ | 1 | /* $NetBSD: specialreg.h,v 1.150.2.6 2020/04/14 17:15:02 martin Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2014-2019 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014-2019 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | /* | 29 | /* | |
30 | * Copyright (c) 1991 The Regents of the University of California. | 30 | * Copyright (c) 1991 The Regents of the University of California. | |
31 | * All rights reserved. | 31 | * All rights reserved. | |
32 | * | 32 | * | |
33 | * Redistribution and use in source and binary forms, with or without | 33 | * Redistribution and use in source and binary forms, with or without | |
34 | * modification, are permitted provided that the following conditions | 34 | * modification, are permitted provided that the following conditions | |
35 | * are met: | 35 | * are met: | |
36 | * 1. Redistributions of source code must retain the above copyright | 36 | * 1. Redistributions of source code must retain the above copyright | |
37 | * notice, this list of conditions and the following disclaimer. | 37 | * notice, this list of conditions and the following disclaimer. | |
38 | * 2. Redistributions in binary form must reproduce the above copyright | 38 | * 2. Redistributions in binary form must reproduce the above copyright | |
39 | * notice, this list of conditions and the following disclaimer in the | 39 | * notice, this list of conditions and the following disclaimer in the | |
40 | * documentation and/or other materials provided with the distribution. | 40 | * documentation and/or other materials provided with the distribution. | |
41 | * 3. Neither the name of the University nor the names of its contributors | 41 | * 3. Neither the name of the University nor the names of its contributors | |
42 | * may be used to endorse or promote products derived from this software | 42 | * may be used to endorse or promote products derived from this software | |
43 | * without specific prior written permission. | 43 | * without specific prior written permission. | |
44 | * | 44 | * | |
45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 45 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
55 | * SUCH DAMAGE. | 55 | * SUCH DAMAGE. | |
56 | * | 56 | * | |
57 | * @(#)specialreg.h 7.1 (Berkeley) 5/9/91 | 57 | * @(#)specialreg.h 7.1 (Berkeley) 5/9/91 | |
58 | */ | 58 | */ | |
59 | 59 | |||
60 | /* | 60 | /* | |
61 | * CR0 | 61 | * CR0 | |
62 | */ | 62 | */ | |
63 | #define CR0_PE 0x00000001 /* Protected mode Enable */ | 63 | #define CR0_PE 0x00000001 /* Protected mode Enable */ | |
64 | #define CR0_MP 0x00000002 /* "Math" Present (NPX or NPX emulator) */ | 64 | #define CR0_MP 0x00000002 /* "Math" Present (NPX or NPX emulator) */ | |
65 | #define CR0_EM 0x00000004 /* EMulate non-NPX coproc. (trap ESC only) */ | 65 | #define CR0_EM 0x00000004 /* EMulate non-NPX coproc. (trap ESC only) */ | |
66 | #define CR0_TS 0x00000008 /* Task Switched (if MP, trap ESC and WAIT) */ | 66 | #define CR0_TS 0x00000008 /* Task Switched (if MP, trap ESC and WAIT) */ | |
67 | #define CR0_ET 0x00000010 /* Extension Type (387 (if set) vs 287) */ | 67 | #define CR0_ET 0x00000010 /* Extension Type (387 (if set) vs 287) */ | |
68 | #define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ | 68 | #define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ | |
69 | #define CR0_WP 0x00010000 /* Write Protect (honor PTE_W in all modes) */ | 69 | #define CR0_WP 0x00010000 /* Write Protect (honor PTE_W in all modes) */ | |
70 | #define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */ | 70 | #define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */ | |
71 | #define CR0_NW 0x20000000 /* Not Write-through */ | 71 | #define CR0_NW 0x20000000 /* Not Write-through */ | |
72 | #define CR0_CD 0x40000000 /* Cache Disable */ | 72 | #define CR0_CD 0x40000000 /* Cache Disable */ | |
73 | #define CR0_PG 0x80000000 /* PaGing enable */ | 73 | #define CR0_PG 0x80000000 /* PaGing enable */ | |
74 | 74 | |||
75 | /* | 75 | /* | |
76 | * Cyrix 486 DLC special registers, accessible as IO ports | 76 | * Cyrix 486 DLC special registers, accessible as IO ports | |
77 | */ | 77 | */ | |
78 | #define CCR0 0xc0 /* configuration control register 0 */ | 78 | #define CCR0 0xc0 /* configuration control register 0 */ | |
79 | #define CCR0_NC0 0x01 /* first 64K of each 1M memory region is non-cacheable */ | 79 | #define CCR0_NC0 0x01 /* first 64K of each 1M memory region is non-cacheable */ | |
80 | #define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */ | 80 | #define CCR0_NC1 0x02 /* 640K-1M region is non-cacheable */ | |
81 | #define CCR0_A20M 0x04 /* enables A20M# input pin */ | 81 | #define CCR0_A20M 0x04 /* enables A20M# input pin */ | |
82 | #define CCR0_KEN 0x08 /* enables KEN# input pin */ | 82 | #define CCR0_KEN 0x08 /* enables KEN# input pin */ | |
83 | #define CCR0_FLUSH 0x10 /* enables FLUSH# input pin */ | 83 | #define CCR0_FLUSH 0x10 /* enables FLUSH# input pin */ | |
84 | #define CCR0_BARB 0x20 /* flushes internal cache when entering hold state */ | 84 | #define CCR0_BARB 0x20 /* flushes internal cache when entering hold state */ | |
85 | #define CCR0_CO 0x40 /* cache org: 1=direct mapped, 0=2x set assoc */ | 85 | #define CCR0_CO 0x40 /* cache org: 1=direct mapped, 0=2x set assoc */ | |
86 | #define CCR0_SUSPEND 0x80 /* enables SUSP# and SUSPA# pins */ | 86 | #define CCR0_SUSPEND 0x80 /* enables SUSP# and SUSPA# pins */ | |
87 | #define CCR1 0xc1 /* configuration control register 1 */ | 87 | #define CCR1 0xc1 /* configuration control register 1 */ | |
88 | #define CCR1_RPL 0x01 /* enables RPLSET and RPLVAL# pins */ | 88 | #define CCR1_RPL 0x01 /* enables RPLSET and RPLVAL# pins */ | |
89 | 89 | |||
90 | /* | 90 | /* | |
91 | * CR3 | 91 | * CR3 | |
92 | */ | 92 | */ | |
93 | #define CR3_PCID __BITS(11,0) | 93 | #define CR3_PCID __BITS(11,0) | |
94 | #define CR3_PA __BITS(62,12) | 94 | #define CR3_PA __BITS(62,12) | |
95 | #define CR3_NO_TLB_FLUSH __BIT(63) | 95 | #define CR3_NO_TLB_FLUSH __BIT(63) | |
96 | 96 | |||
97 | /* | 97 | /* | |
98 | * CR4 | 98 | * CR4 | |
99 | */ | 99 | */ | |
100 | #define CR4_VME 0x00000001 /* virtual 8086 mode extension enable */ | 100 | #define CR4_VME 0x00000001 /* virtual 8086 mode extension enable */ | |
101 | #define CR4_PVI 0x00000002 /* protected mode virtual interrupt enable */ | 101 | #define CR4_PVI 0x00000002 /* protected mode virtual interrupt enable */ | |
102 | #define CR4_TSD 0x00000004 /* restrict RDTSC instruction to cpl 0 */ | 102 | #define CR4_TSD 0x00000004 /* restrict RDTSC instruction to cpl 0 */ | |
103 | #define CR4_DE 0x00000008 /* debugging extension */ | 103 | #define CR4_DE 0x00000008 /* debugging extension */ | |
104 | #define CR4_PSE 0x00000010 /* large (4MB) page size enable */ | 104 | #define CR4_PSE 0x00000010 /* large (4MB) page size enable */ | |
105 | #define CR4_PAE 0x00000020 /* physical address extension enable */ | 105 | #define CR4_PAE 0x00000020 /* physical address extension enable */ | |
106 | #define CR4_MCE 0x00000040 /* machine check enable */ | 106 | #define CR4_MCE 0x00000040 /* machine check enable */ | |
107 | #define CR4_PGE 0x00000080 /* page global enable */ | 107 | #define CR4_PGE 0x00000080 /* page global enable */ | |
108 | #define CR4_PCE 0x00000100 /* enable RDPMC instruction for all cpls */ | 108 | #define CR4_PCE 0x00000100 /* enable RDPMC instruction for all cpls */ | |
109 | #define CR4_OSFXSR 0x00000200 /* enable fxsave/fxrestor and SSE */ | 109 | #define CR4_OSFXSR 0x00000200 /* enable fxsave/fxrestor and SSE */ | |
110 | #define CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ | 110 | #define CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ | |
111 | #define CR4_UMIP 0x00000800 /* user-mode instruction prevention */ | 111 | #define CR4_UMIP 0x00000800 /* user-mode instruction prevention */ | |
112 | #define CR4_VMXE 0x00002000 /* enable VMX operations */ | 112 | #define CR4_VMXE 0x00002000 /* enable VMX operations */ | |
113 | #define CR4_SMXE 0x00004000 /* enable SMX operations */ | 113 | #define CR4_SMXE 0x00004000 /* enable SMX operations */ | |
114 | #define CR4_FSGSBASE 0x00010000 /* enable *FSBASE and *GSBASE instructions */ | 114 | #define CR4_FSGSBASE 0x00010000 /* enable *FSBASE and *GSBASE instructions */ | |
115 | #define CR4_PCIDE 0x00020000 /* enable Process Context IDentifiers */ | 115 | #define CR4_PCIDE 0x00020000 /* enable Process Context IDentifiers */ | |
116 | #define CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ | 116 | #define CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ | |
117 | #define CR4_SMEP 0x00100000 /* enable SMEP support */ | 117 | #define CR4_SMEP 0x00100000 /* enable SMEP support */ | |
118 | #define CR4_SMAP 0x00200000 /* enable SMAP support */ | 118 | #define CR4_SMAP 0x00200000 /* enable SMAP support */ | |
119 | #define CR4_PKE 0x00400000 /* protection key enable */ | 119 | #define CR4_PKE 0x00400000 /* protection key enable */ | |
120 | 120 | |||
121 | /* | 121 | /* | |
122 | * Extended Control Register XCR0 | 122 | * Extended Control Register XCR0 | |
123 | */ | 123 | */ | |
124 | #define XCR0_X87 0x00000001 /* x87 FPU/MMX state */ | 124 | #define XCR0_X87 0x00000001 /* x87 FPU/MMX state */ | |
125 | #define XCR0_SSE 0x00000002 /* SSE state */ | 125 | #define XCR0_SSE 0x00000002 /* SSE state */ | |
126 | #define XCR0_YMM_Hi128 0x00000004 /* AVX-256 (ymmn registers) */ | 126 | #define XCR0_YMM_Hi128 0x00000004 /* AVX-256 (ymmn registers) */ | |
127 | #define XCR0_BNDREGS 0x00000008 /* Memory protection ext bounds */ | 127 | #define XCR0_BNDREGS 0x00000008 /* Memory protection ext bounds */ | |
128 | #define XCR0_BNDCSR 0x00000010 /* Memory protection ext state */ | 128 | #define XCR0_BNDCSR 0x00000010 /* Memory protection ext state */ | |
129 | #define XCR0_Opmask 0x00000020 /* AVX-512 Opmask */ | 129 | #define XCR0_Opmask 0x00000020 /* AVX-512 Opmask */ | |
130 | #define XCR0_ZMM_Hi256 0x00000040 /* AVX-512 upper 256 bits low regs */ | 130 | #define XCR0_ZMM_Hi256 0x00000040 /* AVX-512 upper 256 bits low regs */ | |
131 | #define XCR0_Hi16_ZMM 0x00000080 /* AVX-512 512 bits upper registers */ | 131 | #define XCR0_Hi16_ZMM 0x00000080 /* AVX-512 512 bits upper registers */ | |
132 | #define XCR0_PT 0x00000100 /* Processor Trace state */ | 132 | #define XCR0_PT 0x00000100 /* Processor Trace state */ | |
133 | #define XCR0_PKRU 0x00000200 /* Protection Key state */ | 133 | #define XCR0_PKRU 0x00000200 /* Protection Key state */ | |
134 | #define XCR0_HDC 0x00002000 /* Hardware Duty Cycle state */ | 134 | #define XCR0_HDC 0x00002000 /* Hardware Duty Cycle state */ | |
135 | 135 | |||
136 | #define XCR0_FLAGS1 "\20" \ | 136 | #define XCR0_FLAGS1 "\20" \ | |
137 | "\1" "x87" "\2" "SSE" "\3" "AVX" \ | 137 | "\1" "x87" "\2" "SSE" "\3" "AVX" \ | |
138 | "\4" "BNDREGS" "\5" "BNDCSR" "\6" "Opmask" \ | 138 | "\4" "BNDREGS" "\5" "BNDCSR" "\6" "Opmask" \ | |
139 | "\7" "ZMM_Hi256" "\10" "Hi16_ZMM" "\11" "PT" \ | 139 | "\7" "ZMM_Hi256" "\10" "Hi16_ZMM" "\11" "PT" \ | |
140 | "\12" "PKRU" "\16" "HDC" | 140 | "\12" "PKRU" "\16" "HDC" | |
141 | 141 | |||
142 | /* | 142 | /* | |
143 | * Known FPU bits, only these get enabled. The save area is sized for all the | 143 | * Known FPU bits, only these get enabled. The save area is sized for all the | |
144 | * fields below. | 144 | * fields below. | |
145 | */ | 145 | */ | |
146 | #define XCR0_FPU (XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ | 146 | #define XCR0_FPU (XCR0_X87 | XCR0_SSE | XCR0_YMM_Hi128 | \ | |
147 | XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM) | 147 | XCR0_Opmask | XCR0_ZMM_Hi256 | XCR0_Hi16_ZMM) | |
148 | 148 | |||
149 | /* | 149 | /* | |
150 | * XSAVE component indices. | 150 | * XSAVE component indices. | |
151 | */ | 151 | */ | |
152 | #define XSAVE_X87 0 | 152 | #define XSAVE_X87 0 | |
153 | #define XSAVE_SSE 1 | 153 | #define XSAVE_SSE 1 | |
154 | #define XSAVE_YMM_Hi128 2 | 154 | #define XSAVE_YMM_Hi128 2 | |
155 | #define XSAVE_BNDREGS 3 | 155 | #define XSAVE_BNDREGS 3 | |
156 | #define XSAVE_BNDCSR 4 | 156 | #define XSAVE_BNDCSR 4 | |
157 | #define XSAVE_Opmask 5 | 157 | #define XSAVE_Opmask 5 | |
158 | #define XSAVE_ZMM_Hi256 6 | 158 | #define XSAVE_ZMM_Hi256 6 | |
159 | #define XSAVE_Hi16_ZMM 7 | 159 | #define XSAVE_Hi16_ZMM 7 | |
160 | #define XSAVE_PT 8 | 160 | #define XSAVE_PT 8 | |
161 | #define XSAVE_PKRU 9 | 161 | #define XSAVE_PKRU 9 | |
162 | #define XSAVE_HDC 10 | 162 | #define XSAVE_HDC 10 | |
163 | 163 | |||
164 | /* | 164 | /* | |
165 | * Highest XSAVE component enabled by XCR0_FPU. | 165 | * Highest XSAVE component enabled by XCR0_FPU. | |
166 | */ | 166 | */ | |
167 | #define XSAVE_MAX_COMPONENT XSAVE_Hi16_ZMM | 167 | #define XSAVE_MAX_COMPONENT XSAVE_Hi16_ZMM | |
168 | 168 | |||
169 | /* | 169 | /* | |
170 | * CPUID "features" bits | 170 | * CPUID "features" bits | |
171 | */ | 171 | */ | |
172 | 172 | |||
173 | /* Fn00000001 %edx features */ | 173 | /* Fn00000001 %edx features */ | |
174 | #define CPUID_FPU 0x00000001 /* processor has an FPU? */ | 174 | #define CPUID_FPU 0x00000001 /* processor has an FPU? */ | |
175 | #define CPUID_VME 0x00000002 /* has virtual mode (%cr4's VME/PVI) */ | 175 | #define CPUID_VME 0x00000002 /* has virtual mode (%cr4's VME/PVI) */ | |
176 | #define CPUID_DE 0x00000004 /* has debugging extension */ | 176 | #define CPUID_DE 0x00000004 /* has debugging extension */ | |
177 | #define CPUID_PSE 0x00000008 /* has 4MB page size extension */ | 177 | #define CPUID_PSE 0x00000008 /* has 4MB page size extension */ | |
178 | #define CPUID_TSC 0x00000010 /* has time stamp counter */ | 178 | #define CPUID_TSC 0x00000010 /* has time stamp counter */ | |
179 | #define CPUID_MSR 0x00000020 /* has model specific registers */ | 179 | #define CPUID_MSR 0x00000020 /* has model specific registers */ | |
180 | #define CPUID_PAE 0x00000040 /* has phys address extension */ | 180 | #define CPUID_PAE 0x00000040 /* has phys address extension */ | |
181 | #define CPUID_MCE 0x00000080 /* has machine check exception */ | 181 | #define CPUID_MCE 0x00000080 /* has machine check exception */ | |
182 | #define CPUID_CX8 0x00000100 /* has CMPXCHG8B instruction */ | 182 | #define CPUID_CX8 0x00000100 /* has CMPXCHG8B instruction */ | |
183 | #define CPUID_APIC 0x00000200 /* has enabled APIC */ | 183 | #define CPUID_APIC 0x00000200 /* has enabled APIC */ | |
184 | #define CPUID_B10 0x00000400 /* reserved, MTRR */ | 184 | #define CPUID_B10 0x00000400 /* reserved, MTRR */ | |
185 | #define CPUID_SEP 0x00000800 /* has SYSENTER/SYSEXIT extension */ | 185 | #define CPUID_SEP 0x00000800 /* has SYSENTER/SYSEXIT extension */ | |
186 | #define CPUID_MTRR 0x00001000 /* has memory type range register */ | 186 | #define CPUID_MTRR 0x00001000 /* has memory type range register */ | |
187 | #define CPUID_PGE 0x00002000 /* has page global extension */ | 187 | #define CPUID_PGE 0x00002000 /* has page global extension */ | |
188 | #define CPUID_MCA 0x00004000 /* has machine check architecture */ | 188 | #define CPUID_MCA 0x00004000 /* has machine check architecture */ | |
189 | #define CPUID_CMOV 0x00008000 /* has CMOVcc instruction */ | 189 | #define CPUID_CMOV 0x00008000 /* has CMOVcc instruction */ | |
190 | #define CPUID_PAT 0x00010000 /* Page Attribute Table */ | 190 | #define CPUID_PAT 0x00010000 /* Page Attribute Table */ | |
191 | #define CPUID_PSE36 0x00020000 /* 36-bit PSE */ | 191 | #define CPUID_PSE36 0x00020000 /* 36-bit PSE */ | |
192 | #define CPUID_PN 0x00040000 /* processor serial number */ | 192 | #define CPUID_PN 0x00040000 /* processor serial number */ | |
193 | #define CPUID_CFLUSH 0x00080000 /* CLFLUSH insn supported */ | 193 | #define CPUID_CFLUSH 0x00080000 /* CLFLUSH insn supported */ | |
194 | #define CPUID_B20 0x00100000 /* reserved */ | 194 | #define CPUID_B20 0x00100000 /* reserved */ | |
195 | #define CPUID_DS 0x00200000 /* Debug Store */ | 195 | #define CPUID_DS 0x00200000 /* Debug Store */ | |
196 | #define CPUID_ACPI 0x00400000 /* ACPI performance modulation regs */ | 196 | #define CPUID_ACPI 0x00400000 /* ACPI performance modulation regs */ | |
197 | #define CPUID_MMX 0x00800000 /* MMX supported */ | 197 | #define CPUID_MMX 0x00800000 /* MMX supported */ | |
198 | #define CPUID_FXSR 0x01000000 /* fast FP/MMX save/restore */ | 198 | #define CPUID_FXSR 0x01000000 /* fast FP/MMX save/restore */ | |
199 | #define CPUID_SSE 0x02000000 /* streaming SIMD extensions */ | 199 | #define CPUID_SSE 0x02000000 /* streaming SIMD extensions */ | |
200 | #define CPUID_SSE2 0x04000000 /* streaming SIMD extensions #2 */ | 200 | #define CPUID_SSE2 0x04000000 /* streaming SIMD extensions #2 */ | |
201 | #define CPUID_SS 0x08000000 /* self-snoop */ | 201 | #define CPUID_SS 0x08000000 /* self-snoop */ | |
202 | #define CPUID_HTT 0x10000000 /* Hyper-Threading Technology */ | 202 | #define CPUID_HTT 0x10000000 /* Hyper-Threading Technology */ | |
203 | #define CPUID_TM 0x20000000 /* thermal monitor (TCC) */ | 203 | #define CPUID_TM 0x20000000 /* thermal monitor (TCC) */ | |
204 | #define CPUID_IA64 0x40000000 /* IA-64 architecture */ | 204 | #define CPUID_IA64 0x40000000 /* IA-64 architecture */ | |
205 | #define CPUID_SBF 0x80000000 /* signal break on FERR */ | 205 | #define CPUID_SBF 0x80000000 /* signal break on FERR */ | |
206 | 206 | |||
207 | #define CPUID_FLAGS1 "\20" \ | 207 | #define CPUID_FLAGS1 "\20" \ | |
208 | "\1" "FPU" "\2" "VME" "\3" "DE" "\4" "PSE" \ | 208 | "\1" "FPU" "\2" "VME" "\3" "DE" "\4" "PSE" \ | |
209 | "\5" "TSC" "\6" "MSR" "\7" "PAE" "\10" "MCE" \ | 209 | "\5" "TSC" "\6" "MSR" "\7" "PAE" "\10" "MCE" \ | |
210 | "\11" "CX8" "\12" "APIC" "\13" "B10" "\14" "SEP" \ | 210 | "\11" "CX8" "\12" "APIC" "\13" "B10" "\14" "SEP" \ | |
211 | "\15" "MTRR" "\16" "PGE" "\17" "MCA" "\20" "CMOV" \ | 211 | "\15" "MTRR" "\16" "PGE" "\17" "MCA" "\20" "CMOV" \ | |
212 | "\21" "PAT" "\22" "PSE36" "\23" "PN" "\24" "CLFLUSH" \ | 212 | "\21" "PAT" "\22" "PSE36" "\23" "PN" "\24" "CLFLUSH" \ | |
213 | "\25" "B20" "\26" "DS" "\27" "ACPI" "\30" "MMX" \ | 213 | "\25" "B20" "\26" "DS" "\27" "ACPI" "\30" "MMX" \ | |
214 | "\31" "FXSR" "\32" "SSE" "\33" "SSE2" "\34" "SS" \ | 214 | "\31" "FXSR" "\32" "SSE" "\33" "SSE2" "\34" "SS" \ | |
215 | "\35" "HTT" "\36" "TM" "\37" "IA64" "\40" "SBF" | 215 | "\35" "HTT" "\36" "TM" "\37" "IA64" "\40" "SBF" | |
216 | 216 | |||
217 | /* Blacklists of CPUID flags - used to mask certain features */ | 217 | /* Blacklists of CPUID flags - used to mask certain features */ | |
218 | #ifdef XENPV | 218 | #ifdef XENPV | |
219 | #define CPUID_FEAT_BLACKLIST (CPUID_PGE|CPUID_PSE|CPUID_MTRR) | 219 | #define CPUID_FEAT_BLACKLIST (CPUID_PGE|CPUID_PSE|CPUID_MTRR) | |
220 | #else | 220 | #else | |
221 | #define CPUID_FEAT_BLACKLIST 0 | 221 | #define CPUID_FEAT_BLACKLIST 0 | |
222 | #endif | 222 | #endif | |
223 | 223 | |||
224 | /* | 224 | /* | |
225 | * CPUID "features" bits in Fn00000001 %ecx | 225 | * CPUID "features" bits in Fn00000001 %ecx | |
226 | */ | 226 | */ | |
227 | 227 | |||
228 | #define CPUID2_SSE3 0x00000001 /* Streaming SIMD Extensions 3 */ | 228 | #define CPUID2_SSE3 0x00000001 /* Streaming SIMD Extensions 3 */ | |
229 | #define CPUID2_PCLMUL 0x00000002 /* PCLMULQDQ instructions */ | 229 | #define CPUID2_PCLMUL 0x00000002 /* PCLMULQDQ instructions */ | |
230 | #define CPUID2_DTES64 0x00000004 /* 64-bit Debug Trace */ | 230 | #define CPUID2_DTES64 0x00000004 /* 64-bit Debug Trace */ | |
231 | #define CPUID2_MONITOR 0x00000008 /* MONITOR/MWAIT instructions */ | 231 | #define CPUID2_MONITOR 0x00000008 /* MONITOR/MWAIT instructions */ | |
232 | #define CPUID2_DS_CPL 0x00000010 /* CPL Qualified Debug Store */ | 232 | #define CPUID2_DS_CPL 0x00000010 /* CPL Qualified Debug Store */ | |
233 | #define CPUID2_VMX 0x00000020 /* Virtual Machine Extensions */ | 233 | #define CPUID2_VMX 0x00000020 /* Virtual Machine Extensions */ | |
234 | #define CPUID2_SMX 0x00000040 /* Safer Mode Extensions */ | 234 | #define CPUID2_SMX 0x00000040 /* Safer Mode Extensions */ | |
235 | #define CPUID2_EST 0x00000080 /* Enhanced SpeedStep Technology */ | 235 | #define CPUID2_EST 0x00000080 /* Enhanced SpeedStep Technology */ | |
236 | #define CPUID2_TM2 0x00000100 /* Thermal Monitor 2 */ | 236 | #define CPUID2_TM2 0x00000100 /* Thermal Monitor 2 */ | |
237 | #define CPUID2_SSSE3 0x00000200 /* Supplemental SSE3 */ | 237 | #define CPUID2_SSSE3 0x00000200 /* Supplemental SSE3 */ | |
238 | #define CPUID2_CID 0x00000400 /* Context ID */ | 238 | #define CPUID2_CID 0x00000400 /* Context ID */ | |
239 | #define CPUID2_SDBG 0x00000800 /* Silicon Debug */ | 239 | #define CPUID2_SDBG 0x00000800 /* Silicon Debug */ | |
240 | #define CPUID2_FMA 0x00001000 /* has Fused Multiply Add */ | 240 | #define CPUID2_FMA 0x00001000 /* has Fused Multiply Add */ | |
241 | #define CPUID2_CX16 0x00002000 /* has CMPXCHG16B instruction */ | 241 | #define CPUID2_CX16 0x00002000 /* has CMPXCHG16B instruction */ | |
242 | #define CPUID2_xTPR 0x00004000 /* Task Priority Messages disabled? */ | 242 | #define CPUID2_xTPR 0x00004000 /* Task Priority Messages disabled? */ | |
243 | #define CPUID2_PDCM 0x00008000 /* Perf/Debug Capability MSR */ | 243 | #define CPUID2_PDCM 0x00008000 /* Perf/Debug Capability MSR */ | |
244 | /* bit 16 unused 0x00010000 */ | 244 | /* bit 16 unused 0x00010000 */ | |
245 | #define CPUID2_PCID 0x00020000 /* Process Context ID */ | 245 | #define CPUID2_PCID 0x00020000 /* Process Context ID */ | |
246 | #define CPUID2_DCA 0x00040000 /* Direct Cache Access */ | 246 | #define CPUID2_DCA 0x00040000 /* Direct Cache Access */ | |
247 | #define CPUID2_SSE41 0x00080000 /* Streaming SIMD Extensions 4.1 */ | 247 | #define CPUID2_SSE41 0x00080000 /* Streaming SIMD Extensions 4.1 */ | |
248 | #define CPUID2_SSE42 0x00100000 /* Streaming SIMD Extensions 4.2 */ | 248 | #define CPUID2_SSE42 0x00100000 /* Streaming SIMD Extensions 4.2 */ | |
249 | #define CPUID2_X2APIC 0x00200000 /* xAPIC Extensions */ | 249 | #define CPUID2_X2APIC 0x00200000 /* xAPIC Extensions */ | |
250 | #define CPUID2_MOVBE 0x00400000 /* MOVBE (move after byteswap) */ | 250 | #define CPUID2_MOVBE 0x00400000 /* MOVBE (move after byteswap) */ | |
251 | #define CPUID2_POPCNT 0x00800000 /* popcount instruction available */ | 251 | #define CPUID2_POPCNT 0x00800000 /* popcount instruction available */ | |
252 | #define CPUID2_DEADLINE 0x01000000 /* APIC Timer supports TSC Deadline */ | 252 | #define CPUID2_DEADLINE 0x01000000 /* APIC Timer supports TSC Deadline */ | |
253 | #define CPUID2_AES 0x02000000 /* AES instructions */ | 253 | #define CPUID2_AES 0x02000000 /* AES instructions */ | |
254 | #define CPUID2_XSAVE 0x04000000 /* XSAVE instructions */ | 254 | #define CPUID2_XSAVE 0x04000000 /* XSAVE instructions */ | |
255 | #define CPUID2_OSXSAVE 0x08000000 /* XGETBV/XSETBV instructions */ | 255 | #define CPUID2_OSXSAVE 0x08000000 /* XGETBV/XSETBV instructions */ | |
256 | #define CPUID2_AVX 0x10000000 /* AVX instructions */ | 256 | #define CPUID2_AVX 0x10000000 /* AVX instructions */ | |
257 | #define CPUID2_F16C 0x20000000 /* half precision conversion */ | 257 | #define CPUID2_F16C 0x20000000 /* half precision conversion */ | |
258 | #define CPUID2_RDRAND 0x40000000 /* RDRAND (hardware random number) */ | 258 | #define CPUID2_RDRAND 0x40000000 /* RDRAND (hardware random number) */ | |
259 | #define CPUID2_RAZ 0x80000000 /* RAZ. Indicates guest state. */ | 259 | #define CPUID2_RAZ 0x80000000 /* RAZ. Indicates guest state. */ | |
260 | 260 | |||
261 | #define CPUID2_FLAGS1 "\20" \ | 261 | #define CPUID2_FLAGS1 "\20" \ | |
262 | "\1" "SSE3" "\2" "PCLMULQDQ" "\3" "DTES64" "\4" "MONITOR" \ | 262 | "\1" "SSE3" "\2" "PCLMULQDQ" "\3" "DTES64" "\4" "MONITOR" \ | |
263 | "\5" "DS-CPL" "\6" "VMX" "\7" "SMX" "\10" "EST" \ | 263 | "\5" "DS-CPL" "\6" "VMX" "\7" "SMX" "\10" "EST" \ | |
264 | "\11" "TM2" "\12" "SSSE3" "\13" "CID" "\14" "SDBG" \ | 264 | "\11" "TM2" "\12" "SSSE3" "\13" "CID" "\14" "SDBG" \ | |
265 | "\15" "FMA" "\16" "CX16" "\17" "xTPR" "\20" "PDCM" \ | 265 | "\15" "FMA" "\16" "CX16" "\17" "xTPR" "\20" "PDCM" \ | |
266 | "\21" "B16" "\22" "PCID" "\23" "DCA" "\24" "SSE41" \ | 266 | "\21" "B16" "\22" "PCID" "\23" "DCA" "\24" "SSE41" \ | |
267 | "\25" "SSE42" "\26" "X2APIC" "\27" "MOVBE" "\30" "POPCNT" \ | 267 | "\25" "SSE42" "\26" "X2APIC" "\27" "MOVBE" "\30" "POPCNT" \ | |
268 | "\31" "DEADLINE" "\32" "AES" "\33" "XSAVE" "\34" "OSXSAVE" \ | 268 | "\31" "DEADLINE" "\32" "AES" "\33" "XSAVE" "\34" "OSXSAVE" \ | |
269 | "\35" "AVX" "\36" "F16C" "\37" "RDRAND" "\40" "RAZ" | 269 | "\35" "AVX" "\36" "F16C" "\37" "RDRAND" "\40" "RAZ" | |
270 | 270 | |||
271 | /* CPUID Fn00000001 %eax */ | 271 | /* CPUID Fn00000001 %eax */ | |
272 | 272 | |||
273 | #define CPUID_TO_BASEFAMILY(cpuid) (((cpuid) >> 8) & 0xf) | 273 | #define CPUID_TO_BASEFAMILY(cpuid) (((cpuid) >> 8) & 0xf) | |
274 | #define CPUID_TO_BASEMODEL(cpuid) (((cpuid) >> 4) & 0xf) | 274 | #define CPUID_TO_BASEMODEL(cpuid) (((cpuid) >> 4) & 0xf) | |
275 | #define CPUID_TO_STEPPING(cpuid) ((cpuid) & 0xf) | 275 | #define CPUID_TO_STEPPING(cpuid) ((cpuid) & 0xf) | |
276 | 276 | |||
277 | /* | 277 | /* | |
278 | * The Extended family bits should only be inspected when CPUID_TO_BASEFAMILY() | 278 | * The Extended family bits should only be inspected when CPUID_TO_BASEFAMILY() | |
279 | * returns 15. They are use to encode family value 16 to 270 (add 15). | 279 | * returns 15. They are use to encode family value 16 to 270 (add 15). | |
280 | * The Extended model bits are the high 4 bits of the model. | 280 | * The Extended model bits are the high 4 bits of the model. | |
281 | * They are only valid for family >= 15 or family 6 (intel, but all amd | 281 | * They are only valid for family >= 15 or family 6 (intel, but all amd | |
282 | * family 6 are documented to return zero bits for them). | 282 | * family 6 are documented to return zero bits for them). | |
283 | */ | 283 | */ | |
284 | #define CPUID_TO_EXTFAMILY(cpuid) (((cpuid) >> 20) & 0xff) | 284 | #define CPUID_TO_EXTFAMILY(cpuid) (((cpuid) >> 20) & 0xff) | |
285 | #define CPUID_TO_EXTMODEL(cpuid) (((cpuid) >> 16) & 0xf) | 285 | #define CPUID_TO_EXTMODEL(cpuid) (((cpuid) >> 16) & 0xf) | |
286 | 286 | |||
287 | /* The macros for the Display Family and the Display Model */ | 287 | /* The macros for the Display Family and the Display Model */ | |
288 | #define CPUID_TO_FAMILY(cpuid) (CPUID_TO_BASEFAMILY(cpuid) \ | 288 | #define CPUID_TO_FAMILY(cpuid) (CPUID_TO_BASEFAMILY(cpuid) \ | |
289 | + ((CPUID_TO_BASEFAMILY(cpuid) != 0x0f) \ | 289 | + ((CPUID_TO_BASEFAMILY(cpuid) != 0x0f) \ | |
290 | ? 0 : CPUID_TO_EXTFAMILY(cpuid))) | 290 | ? 0 : CPUID_TO_EXTFAMILY(cpuid))) | |
291 | #define CPUID_TO_MODEL(cpuid) (CPUID_TO_BASEMODEL(cpuid) \ | 291 | #define CPUID_TO_MODEL(cpuid) (CPUID_TO_BASEMODEL(cpuid) \ | |
292 | | ((CPUID_TO_BASEFAMILY(cpuid) != 0x0f) \ | 292 | | ((CPUID_TO_BASEFAMILY(cpuid) != 0x0f) \ | |
293 | && (CPUID_TO_BASEFAMILY(cpuid) != 0x06) \ | 293 | && (CPUID_TO_BASEFAMILY(cpuid) != 0x06) \ | |
294 | ? 0 : (CPUID_TO_EXTMODEL(cpuid) << 4))) | 294 | ? 0 : (CPUID_TO_EXTMODEL(cpuid) << 4))) | |
295 | 295 | |||
296 | /* CPUID Fn00000001 %ebx */ | 296 | /* CPUID Fn00000001 %ebx */ | |
297 | #define CPUID_BRAND_INDEX __BITS(7,0) | 297 | #define CPUID_BRAND_INDEX __BITS(7,0) | |
298 | #define CPUID_CLFLUSH_SIZE __BITS(15,8) | 298 | #define CPUID_CLFLUSH_SIZE __BITS(15,8) | |
299 | #define CPUID_HTT_CORES __BITS(23,16) | 299 | #define CPUID_HTT_CORES __BITS(23,16) | |
300 | #define CPUID_LOCAL_APIC_ID __BITS(31,24) | 300 | #define CPUID_LOCAL_APIC_ID __BITS(31,24) | |
301 | 301 | |||
302 | /* | 302 | /* | |
303 | * Intel Deterministic Cache Parameter Leaf | 303 | * Intel Deterministic Cache Parameter Leaf | |
304 | * Fn0000_0004 | 304 | * Fn0000_0004 | |
305 | */ | 305 | */ | |
306 | 306 | |||
307 | /* %eax */ | 307 | /* %eax */ | |
308 | #define CPUID_DCP_CACHETYPE __BITS(4, 0) /* Cache type */ | 308 | #define CPUID_DCP_CACHETYPE __BITS(4, 0) /* Cache type */ | |
309 | #define CPUID_DCP_CACHETYPE_N 0 /* NULL */ | 309 | #define CPUID_DCP_CACHETYPE_N 0 /* NULL */ | |
310 | #define CPUID_DCP_CACHETYPE_D 1 /* Data cache */ | 310 | #define CPUID_DCP_CACHETYPE_D 1 /* Data cache */ | |
311 | #define CPUID_DCP_CACHETYPE_I 2 /* Instruction cache */ | 311 | #define CPUID_DCP_CACHETYPE_I 2 /* Instruction cache */ | |
312 | #define CPUID_DCP_CACHETYPE_U 3 /* Unified cache */ | 312 | #define CPUID_DCP_CACHETYPE_U 3 /* Unified cache */ | |
313 | #define CPUID_DCP_CACHELEVEL __BITS(7, 5) /* Cache level (start at 1) */ | 313 | #define CPUID_DCP_CACHELEVEL __BITS(7, 5) /* Cache level (start at 1) */ | |
314 | #define CPUID_DCP_SELFINITCL __BIT(8) /* Self initializing cachelvl*/ | 314 | #define CPUID_DCP_SELFINITCL __BIT(8) /* Self initializing cachelvl*/ | |
315 | #define CPUID_DCP_FULLASSOC __BIT(9) /* Full associative */ | 315 | #define CPUID_DCP_FULLASSOC __BIT(9) /* Full associative */ | |
316 | #define CPUID_DCP_SHAREING __BITS(25, 14) /* shareing */ | 316 | #define CPUID_DCP_SHAREING __BITS(25, 14) /* shareing */ | |
317 | #define CPUID_DCP_CORE_P_PKG __BITS(31, 26) /* Cores/package */ | 317 | #define CPUID_DCP_CORE_P_PKG __BITS(31, 26) /* Cores/package */ | |
318 | 318 | |||
319 | /* %ebx */ | 319 | /* %ebx */ | |
320 | #define CPUID_DCP_LINESIZE __BITS(11, 0) /* System coherency linesize */ | 320 | #define CPUID_DCP_LINESIZE __BITS(11, 0) /* System coherency linesize */ | |
321 | #define CPUID_DCP_PARTITIONS __BITS(21, 12) /* Physical line partitions */ | 321 | #define CPUID_DCP_PARTITIONS __BITS(21, 12) /* Physical line partitions */ | |
322 | #define CPUID_DCP_WAYS __BITS(31, 22) /* Ways of associativity */ | 322 | #define CPUID_DCP_WAYS __BITS(31, 22) /* Ways of associativity */ | |
323 | 323 | |||
324 | /* Number of sets: %ecx */ | 324 | /* Number of sets: %ecx */ | |
325 | 325 | |||
326 | /* %edx */ | 326 | /* %edx */ | |
327 | #define CPUID_DCP_INVALIDATE __BIT(0) /* WB invalidate/invalidate */ | 327 | #define CPUID_DCP_INVALIDATE __BIT(0) /* WB invalidate/invalidate */ | |
328 | #define CPUID_DCP_INCLUSIVE __BIT(1) /* Cache inclusiveness */ | 328 | #define CPUID_DCP_INCLUSIVE __BIT(1) /* Cache inclusiveness */ | |
329 | #define CPUID_DCP_COMPLEX __BIT(2) /* Complex cache indexing */ | 329 | #define CPUID_DCP_COMPLEX __BIT(2) /* Complex cache indexing */ | |
330 | 330 | |||
331 | /* | 331 | /* | |
332 | * Intel/AMD MONITOR/MWAIT | 332 | * Intel/AMD MONITOR/MWAIT | |
333 | * Fn0000_0005 | 333 | * Fn0000_0005 | |
334 | */ | 334 | */ | |
335 | /* %eax */ | 335 | /* %eax */ | |
336 | #define CPUID_MON_MINSIZE __BITS(15, 0) /* Smallest monitor-line size */ | 336 | #define CPUID_MON_MINSIZE __BITS(15, 0) /* Smallest monitor-line size */ | |
337 | /* %ebx */ | 337 | /* %ebx */ | |
338 | #define CPUID_MON_MAXSIZE __BITS(15, 0) /* Largest monitor-line size */ | 338 | #define CPUID_MON_MAXSIZE __BITS(15, 0) /* Largest monitor-line size */ | |
339 | /* %ecx */ | 339 | /* %ecx */ | |
340 | #define CPUID_MON_EMX __BIT(0) /* MONITOR/MWAIT Extensions */ | 340 | #define CPUID_MON_EMX __BIT(0) /* MONITOR/MWAIT Extensions */ | |
341 | #define CPUID_MON_IBE __BIT(1) /* Interrupt as Break Event */ | 341 | #define CPUID_MON_IBE __BIT(1) /* Interrupt as Break Event */ | |
342 | 342 | |||
343 | #define CPUID_MON_FLAGS "\20" \ | 343 | #define CPUID_MON_FLAGS "\20" \ | |
344 | "\1" "EMX" "\2" "IBE" | 344 | "\1" "EMX" "\2" "IBE" | |
345 | 345 | |||
346 | /* %edx: number of substates for specific C-state */ | 346 | /* %edx: number of substates for specific C-state */ | |
347 | #define CPUID_MON_SUBSTATE(edx, cstate) (((edx) >> (cstate * 4)) & 0x0000000f) | 347 | #define CPUID_MON_SUBSTATE(edx, cstate) (((edx) >> (cstate * 4)) & 0x0000000f) | |
348 | 348 | |||
349 | /* | 349 | /* | |
350 | * Intel/AMD Digital Thermal Sensor and | 350 | * Intel/AMD Digital Thermal Sensor and | |
351 | * Power Management, Fn0000_0006 - %eax. | 351 | * Power Management, Fn0000_0006 - %eax. | |
352 | */ | 352 | */ | |
353 | #define CPUID_DSPM_DTS __BIT(0) /* Digital Thermal Sensor */ | 353 | #define CPUID_DSPM_DTS __BIT(0) /* Digital Thermal Sensor */ | |
354 | #define CPUID_DSPM_IDA __BIT(1) /* Intel Dynamic Acceleration */ | 354 | #define CPUID_DSPM_IDA __BIT(1) /* Intel Dynamic Acceleration */ | |
355 | #define CPUID_DSPM_ARAT __BIT(2) /* Always Running APIC Timer */ | 355 | #define CPUID_DSPM_ARAT __BIT(2) /* Always Running APIC Timer */ | |
356 | #define CPUID_DSPM_PLN __BIT(4) /* Power Limit Notification */ | 356 | #define CPUID_DSPM_PLN __BIT(4) /* Power Limit Notification */ | |
357 | #define CPUID_DSPM_ECMD __BIT(5) /* Clock Modulation Extension */ | 357 | #define CPUID_DSPM_ECMD __BIT(5) /* Clock Modulation Extension */ | |
358 | #define CPUID_DSPM_PTM __BIT(6) /* Package Level Thermal Management */ | 358 | #define CPUID_DSPM_PTM __BIT(6) /* Package Level Thermal Management */ | |
359 | #define CPUID_DSPM_HWP __BIT(7) /* HWP */ | 359 | #define CPUID_DSPM_HWP __BIT(7) /* HWP */ | |
360 | #define CPUID_DSPM_HWP_NOTIFY __BIT(8) /* HWP Notification */ | 360 | #define CPUID_DSPM_HWP_NOTIFY __BIT(8) /* HWP Notification */ | |
361 | #define CPUID_DSPM_HWP_ACTWIN __BIT(9) /* HWP Activity Window */ | 361 | #define CPUID_DSPM_HWP_ACTWIN __BIT(9) /* HWP Activity Window */ | |
362 | #define CPUID_DSPM_HWP_EPP __BIT(10) /* HWP Energy Performance Preference */ | 362 | #define CPUID_DSPM_HWP_EPP __BIT(10) /* HWP Energy Performance Preference */ | |
363 | #define CPUID_DSPM_HWP_PLR __BIT(11) /* HWP Package Level Request */ | 363 | #define CPUID_DSPM_HWP_PLR __BIT(11) /* HWP Package Level Request */ | |
364 | #define CPUID_DSPM_HDC __BIT(13) /* Hardware Duty Cycling */ | 364 | #define CPUID_DSPM_HDC __BIT(13) /* Hardware Duty Cycling */ | |
365 | #define CPUID_DSPM_TBMT3 __BIT(14) /* Turbo Boost Max Technology 3.0 */ | 365 | #define CPUID_DSPM_TBMT3 __BIT(14) /* Turbo Boost Max Technology 3.0 */ | |
366 | #define CPUID_DSPM_HWP_CAP __BIT(15) /* HWP Capabilities */ | 366 | #define CPUID_DSPM_HWP_CAP __BIT(15) /* HWP Capabilities */ | |
367 | #define CPUID_DSPM_HWP_PECI __BIT(16) /* HWP PECI override */ | 367 | #define CPUID_DSPM_HWP_PECI __BIT(16) /* HWP PECI override */ | |
368 | #define CPUID_DSPM_HWP_FLEX __BIT(17) /* Flexible HWP */ | 368 | #define CPUID_DSPM_HWP_FLEX __BIT(17) /* Flexible HWP */ | |
369 | #define CPUID_DSPM_HWP_FAST __BIT(18) /* Fast access for IA32_HWP_REQUEST */ | 369 | #define CPUID_DSPM_HWP_FAST __BIT(18) /* Fast access for IA32_HWP_REQUEST */ | |
370 | #define CPUID_DSPM_HWP_IGNIDL __BIT(20) /* Ignore Idle Logical Processor HWP */ | 370 | #define CPUID_DSPM_HWP_IGNIDL __BIT(20) /* Ignore Idle Logical Processor HWP */ | |
371 | 371 | |||
372 | #define CPUID_DSPM_FLAGS "\20" \ | 372 | #define CPUID_DSPM_FLAGS "\20" \ | |
373 | "\1" "DTS" "\2" "IDA" "\3" "ARAT" \ | 373 | "\1" "DTS" "\2" "IDA" "\3" "ARAT" \ | |
374 | "\5" "PLN" "\6" "ECMD" "\7" "PTM" "\10" "HWP" \ | 374 | "\5" "PLN" "\6" "ECMD" "\7" "PTM" "\10" "HWP" \ | |
375 | "\11" "HWP_NOTIFY" "\12" "HWP_ACTWIN" "\13" "HWP_EPP" "\14" "HWP_PLR" \ | 375 | "\11" "HWP_NOTIFY" "\12" "HWP_ACTWIN" "\13" "HWP_EPP" "\14" "HWP_PLR" \ | |
376 | "\16" "HDC" "\17" "TBM3" "\20" "HWP_CAP" \ | 376 | "\16" "HDC" "\17" "TBM3" "\20" "HWP_CAP" \ | |
377 | "\21" "HWP_PECI" "\22" "HWP_FLEX" "\23" "HWP_FAST" \ | 377 | "\21" "HWP_PECI" "\22" "HWP_FLEX" "\23" "HWP_FAST" \ | |
378 | "25" "HWP_IGNIDL" | 378 | "25" "HWP_IGNIDL" | |
379 | 379 | |||
380 | /* | 380 | /* | |
381 | * Intel/AMD Digital Thermal Sensor and | 381 | * Intel/AMD Digital Thermal Sensor and | |
382 | * Power Management, Fn0000_0006 - %ecx. | 382 | * Power Management, Fn0000_0006 - %ecx. | |
383 | */ | 383 | */ | |
384 | #define CPUID_DSPM_HWF 0x00000001 /* MSR_APERF/MSR_MPERF available */ | 384 | #define CPUID_DSPM_HWF 0x00000001 /* MSR_APERF/MSR_MPERF available */ | |
385 | #define CPUID_DSPM_EPB 0x00000008 /* Energy Performance Bias */ | 385 | #define CPUID_DSPM_EPB 0x00000008 /* Energy Performance Bias */ | |
386 | 386 | |||
387 | #define CPUID_DSPM_FLAGS1 "\20" "\1" "HWF" "\4" "EPB" | 387 | #define CPUID_DSPM_FLAGS1 "\20" "\1" "HWF" "\4" "EPB" | |
388 | 388 | |||
389 | /* | 389 | /* | |
390 | * Intel/AMD Structured Extended Feature leaf Fn0000_0007 | 390 | * Intel/AMD Structured Extended Feature leaf Fn0000_0007 | |
391 | * %eax == 0: Subleaf 0 | 391 | * %eax == 0: Subleaf 0 | |
392 | * %eax: The Maximum input value for supported subleaf. | 392 | * %eax: The Maximum input value for supported subleaf. | |
393 | * %ebx: Feature bits. | 393 | * %ebx: Feature bits. | |
394 | * %ecx: Feature bits. | 394 | * %ecx: Feature bits. | |
395 | * %edx: Feature bits. | 395 | * %edx: Feature bits. | |
396 | */ | 396 | */ | |
397 | 397 | |||
398 | /* %ebx */ | 398 | /* %ebx */ | |
399 | #define CPUID_SEF_FSGSBASE __BIT(0) /* {RD,WR}{FS,GS}BASE */ | 399 | #define CPUID_SEF_FSGSBASE __BIT(0) /* {RD,WR}{FS,GS}BASE */ | |
400 | #define CPUID_SEF_TSC_ADJUST __BIT(1) /* IA32_TSC_ADJUST MSR support */ | 400 | #define CPUID_SEF_TSC_ADJUST __BIT(1) /* IA32_TSC_ADJUST MSR support */ | |
401 | #define CPUID_SEF_SGX __BIT(2) /* Software Guard Extensions */ | 401 | #define CPUID_SEF_SGX __BIT(2) /* Software Guard Extensions */ | |
402 | #define CPUID_SEF_BMI1 __BIT(3) /* advanced bit manipulation ext. 1st grp */ | 402 | #define CPUID_SEF_BMI1 __BIT(3) /* advanced bit manipulation ext. 1st grp */ | |
403 | #define CPUID_SEF_HLE __BIT(4) /* Hardware Lock Elision */ | 403 | #define CPUID_SEF_HLE __BIT(4) /* Hardware Lock Elision */ | |
404 | #define CPUID_SEF_AVX2 __BIT(5) /* Advanced Vector Extensions 2 */ | 404 | #define CPUID_SEF_AVX2 __BIT(5) /* Advanced Vector Extensions 2 */ | |
405 | #define CPUID_SEF_FDPEXONLY __BIT(6) /* x87FPU Data ptr updated only on x87exp */ | 405 | #define CPUID_SEF_FDPEXONLY __BIT(6) /* x87FPU Data ptr updated only on x87exp */ | |
406 | #define CPUID_SEF_SMEP __BIT(7) /* Supervisor-Mode Execution Prevention */ | 406 | #define CPUID_SEF_SMEP __BIT(7) /* Supervisor-Mode Execution Prevention */ | |
407 | #define CPUID_SEF_BMI2 __BIT(8) /* advanced bit manipulation ext. 2nd grp */ | 407 | #define CPUID_SEF_BMI2 __BIT(8) /* advanced bit manipulation ext. 2nd grp */ | |
408 | #define CPUID_SEF_ERMS __BIT(9) /* Enhanced REP MOVSB/STOSB */ | 408 | #define CPUID_SEF_ERMS __BIT(9) /* Enhanced REP MOVSB/STOSB */ | |
409 | #define CPUID_SEF_INVPCID __BIT(10) /* INVPCID instruction */ | 409 | #define CPUID_SEF_INVPCID __BIT(10) /* INVPCID instruction */ | |
410 | #define CPUID_SEF_RTM __BIT(11) /* Restricted Transactional Memory */ | 410 | #define CPUID_SEF_RTM __BIT(11) /* Restricted Transactional Memory */ | |
411 | #define CPUID_SEF_QM __BIT(12) /* Resource Director Technology Monitoring */ | 411 | #define CPUID_SEF_QM __BIT(12) /* Resource Director Technology Monitoring */ | |
412 | #define CPUID_SEF_FPUCSDS __BIT(13) /* Deprecate FPU CS and FPU DS values */ | 412 | #define CPUID_SEF_FPUCSDS __BIT(13) /* Deprecate FPU CS and FPU DS values */ | |
413 | #define CPUID_SEF_MPX __BIT(14) /* Memory Protection Extensions */ | 413 | #define CPUID_SEF_MPX __BIT(14) /* Memory Protection Extensions */ | |
414 | #define CPUID_SEF_PQE __BIT(15) /* Resource Director Technology Allocation */ | 414 | #define CPUID_SEF_PQE __BIT(15) /* Resource Director Technology Allocation */ | |
415 | #define CPUID_SEF_AVX512F __BIT(16) /* AVX-512 Foundation */ | 415 | #define CPUID_SEF_AVX512F __BIT(16) /* AVX-512 Foundation */ | |
416 | #define CPUID_SEF_AVX512DQ __BIT(17) /* AVX-512 Double/Quadword */ | 416 | #define CPUID_SEF_AVX512DQ __BIT(17) /* AVX-512 Double/Quadword */ | |
417 | #define CPUID_SEF_RDSEED __BIT(18) /* RDSEED instruction */ | 417 | #define CPUID_SEF_RDSEED __BIT(18) /* RDSEED instruction */ | |
418 | #define CPUID_SEF_ADX __BIT(19) /* ADCX/ADOX instructions */ | 418 | #define CPUID_SEF_ADX __BIT(19) /* ADCX/ADOX instructions */ | |
419 | #define CPUID_SEF_SMAP __BIT(20) /* Supervisor-Mode Access Prevention */ | 419 | #define CPUID_SEF_SMAP __BIT(20) /* Supervisor-Mode Access Prevention */ | |
420 | #define CPUID_SEF_AVX512_IFMA __BIT(21) /* AVX-512 Integer Fused Multiply Add */ | 420 | #define CPUID_SEF_AVX512_IFMA __BIT(21) /* AVX-512 Integer Fused Multiply Add */ | |
421 | /* Bit 22 was PCOMMIT */ | 421 | /* Bit 22 was PCOMMIT */ | |
422 | #define CPUID_SEF_CLFLUSHOPT __BIT(23) /* Cache Line FLUSH OPTimized */ | 422 | #define CPUID_SEF_CLFLUSHOPT __BIT(23) /* Cache Line FLUSH OPTimized */ | |
423 | #define CPUID_SEF_CLWB __BIT(24) /* Cache Line Write Back */ | 423 | #define CPUID_SEF_CLWB __BIT(24) /* Cache Line Write Back */ | |
424 | #define CPUID_SEF_PT __BIT(25) /* Processor Trace */ | 424 | #define CPUID_SEF_PT __BIT(25) /* Processor Trace */ | |
425 | #define CPUID_SEF_AVX512PF __BIT(26) /* AVX-512 PreFetch */ | 425 | #define CPUID_SEF_AVX512PF __BIT(26) /* AVX-512 PreFetch */ | |
426 | #define CPUID_SEF_AVX512ER __BIT(27) /* AVX-512 Exponential and Reciprocal */ | 426 | #define CPUID_SEF_AVX512ER __BIT(27) /* AVX-512 Exponential and Reciprocal */ | |
427 | #define CPUID_SEF_AVX512CD __BIT(28) /* AVX-512 Conflict Detection */ | 427 | #define CPUID_SEF_AVX512CD __BIT(28) /* AVX-512 Conflict Detection */ | |
428 | #define CPUID_SEF_SHA __BIT(29) /* SHA Extensions */ | 428 | #define CPUID_SEF_SHA __BIT(29) /* SHA Extensions */ | |
429 | #define CPUID_SEF_AVX512BW __BIT(30) /* AVX-512 Byte and Word */ | 429 | #define CPUID_SEF_AVX512BW __BIT(30) /* AVX-512 Byte and Word */ | |
430 | #define CPUID_SEF_AVX512VL __BIT(31) /* AVX-512 Vector Length */ | 430 | #define CPUID_SEF_AVX512VL __BIT(31) /* AVX-512 Vector Length */ | |
431 | 431 | |||
432 | #define CPUID_SEF_FLAGS "\20" \ | 432 | #define CPUID_SEF_FLAGS "\20" \ | |
433 | "\1" "FSGSBASE" "\2" "TSCADJUST" "\3" "SGX" "\4" "BMI1" \ | 433 | "\1" "FSGSBASE" "\2" "TSCADJUST" "\3" "SGX" "\4" "BMI1" \ | |
434 | "\5" "HLE" "\6" "AVX2" "\7" "FDPEXONLY" "\10" "SMEP" \ | 434 | "\5" "HLE" "\6" "AVX2" "\7" "FDPEXONLY" "\10" "SMEP" \ | |
435 | "\11" "BMI2" "\12" "ERMS" "\13" "INVPCID" "\14" "RTM" \ | 435 | "\11" "BMI2" "\12" "ERMS" "\13" "INVPCID" "\14" "RTM" \ | |
436 | "\15" "QM" "\16" "FPUCSDS" "\17" "MPX" "\20" "PQE" \ | 436 | "\15" "QM" "\16" "FPUCSDS" "\17" "MPX" "\20" "PQE" \ | |
437 | "\21" "AVX512F" "\22" "AVX512DQ" "\23" "RDSEED" "\24" "ADX" \ | 437 | "\21" "AVX512F" "\22" "AVX512DQ" "\23" "RDSEED" "\24" "ADX" \ | |
438 | "\25" "SMAP" "\26" "AVX512_IFMA" "\30" "CLFLUSHOPT" \ | 438 | "\25" "SMAP" "\26" "AVX512_IFMA" "\30" "CLFLUSHOPT" \ | |
439 | "\31" "CLWB" "\32" "PT" "\33" "AVX512PF" "\34" "AVX512ER" \ | 439 | "\31" "CLWB" "\32" "PT" "\33" "AVX512PF" "\34" "AVX512ER" \ | |
440 | "\35" "AVX512CD""\36" "SHA" "\37" "AVX512BW" "\40" "AVX512VL" | 440 | "\35" "AVX512CD""\36" "SHA" "\37" "AVX512BW" "\40" "AVX512VL" | |
441 | 441 | |||
442 | /* %ecx */ | 442 | /* %ecx */ | |
443 | #define CPUID_SEF_PREFETCHWT1 __BIT(0) /* PREFETCHWT1 instruction */ | 443 | #define CPUID_SEF_PREFETCHWT1 __BIT(0) /* PREFETCHWT1 instruction */ | |
444 | #define CPUID_SEF_AVX512_VBMI __BIT(1) /* AVX-512 Vector Byte Manipulation */ | 444 | #define CPUID_SEF_AVX512_VBMI __BIT(1) /* AVX-512 Vector Byte Manipulation */ | |
445 | #define CPUID_SEF_UMIP __BIT(2) /* User-Mode Instruction prevention */ | 445 | #define CPUID_SEF_UMIP __BIT(2) /* User-Mode Instruction prevention */ | |
446 | #define CPUID_SEF_PKU __BIT(3) /* Protection Keys for User-mode pages */ | 446 | #define CPUID_SEF_PKU __BIT(3) /* Protection Keys for User-mode pages */ | |
447 | #define CPUID_SEF_OSPKE __BIT(4) /* OS has set CR4.PKE to ena. protec. keys */ | 447 | #define CPUID_SEF_OSPKE __BIT(4) /* OS has set CR4.PKE to ena. protec. keys */ | |
448 | #define CPUID_SEF_WAITPKG __BIT(5) /* TPAUSE,UMONITOR,UMWAIT */ | 448 | #define CPUID_SEF_WAITPKG __BIT(5) /* TPAUSE,UMONITOR,UMWAIT */ | |
449 | #define CPUID_SEF_AVX512_VBMI2 __BIT(6) /* AVX-512 Vector Byte Manipulation 2 */ | 449 | #define CPUID_SEF_AVX512_VBMI2 __BIT(6) /* AVX-512 Vector Byte Manipulation 2 */ | |
450 | #define CPUID_SEF_CET_SS __BIT(7) /* CET shadow stack */ | 450 | #define CPUID_SEF_CET_SS __BIT(7) /* CET shadow stack */ | |
451 | #define CPUID_SEF_GFNI __BIT(8) | 451 | #define CPUID_SEF_GFNI __BIT(8) | |
452 | #define CPUID_SEF_VAES __BIT(9) | 452 | #define CPUID_SEF_VAES __BIT(9) | |
453 | #define CPUID_SEF_VPCLMULQDQ __BIT(10) | 453 | #define CPUID_SEF_VPCLMULQDQ __BIT(10) | |
454 | #define CPUID_SEF_AVX512_VNNI __BIT(11) /* Vector neural Network Instruction */ | 454 | #define CPUID_SEF_AVX512_VNNI __BIT(11) /* Vector neural Network Instruction */ | |
455 | #define CPUID_SEF_AVX512_BITALG __BIT(12) | 455 | #define CPUID_SEF_AVX512_BITALG __BIT(12) | |
456 | #define CPUID_SEF_AVX512_VPOPCNTDQ __BIT(14) | 456 | #define CPUID_SEF_AVX512_VPOPCNTDQ __BIT(14) | |
457 | #define CPUID_SEF_MAWAU __BITS(21, 17) /* MAWAU for BND{LD,ST}X */ | 457 | #define CPUID_SEF_MAWAU __BITS(21, 17) /* MAWAU for BND{LD,ST}X */ | |
458 | #define CPUID_SEF_RDPID __BIT(22) /* RDPID and IA32_TSC_AUX */ | 458 | #define CPUID_SEF_RDPID __BIT(22) /* RDPID and IA32_TSC_AUX */ | |
459 | #define CPUID_SEF_CLDEMOTE __BIT(25) /* Cache line demote */ | 459 | #define CPUID_SEF_CLDEMOTE __BIT(25) /* Cache line demote */ | |
460 | #define CPUID_SEF_MOVDIRI __BIT(27) /* MOVDIRI instruction */ | 460 | #define CPUID_SEF_MOVDIRI __BIT(27) /* MOVDIRI instruction */ | |
461 | #define CPUID_SEF_MOVDIR64B __BIT(28) /* MOVDIR64B instruction */ | 461 | #define CPUID_SEF_MOVDIR64B __BIT(28) /* MOVDIR64B instruction */ | |
462 | #define CPUID_SEF_SGXLC __BIT(30) /* SGX Launch Configuration */ | 462 | #define CPUID_SEF_SGXLC __BIT(30) /* SGX Launch Configuration */ | |
463 | 463 | |||
464 | #define CPUID_SEF_FLAGS1 "\177\20" \ | 464 | #define CPUID_SEF_FLAGS1 "\177\20" \ | |
465 | "b\0PREFETCHWT1\0" "b\1AVX512_VBMI\0" "b\2UMIP\0" "b\3PKU\0" \ | 465 | "b\0PREFETCHWT1\0" "b\1AVX512_VBMI\0" "b\2UMIP\0" "b\3PKU\0" \ | |
466 | "b\4OSPKE\0" "b\5WAITPKG\0" "b\6AVX512_VBMI2\0" "b\7CET_SS\0" \ | 466 | "b\4OSPKE\0" "b\5WAITPKG\0" "b\6AVX512_VBMI2\0" "b\7CET_SS\0" \ | |
467 | "b\10GFNI\0" "b\11VAES\0" "b\12VPCLMULQDQ\0" "b\13AVX512_VNNI\0"\ | 467 | "b\10GFNI\0" "b\11VAES\0" "b\12VPCLMULQDQ\0" "b\13AVX512_VNNI\0"\ | |
468 | "b\14AVX512_BITALG\0" "b\16AVX512_VPOPCNTDQ\0" \ | 468 | "b\14AVX512_BITALG\0" "b\16AVX512_VPOPCNTDQ\0" \ | |
469 | "f\21\5MAWAU\0" \ | 469 | "f\21\5MAWAU\0" \ | |
470 | "b\26RDPID\0" \ | 470 | "b\26RDPID\0" \ | |
471 | "b\31CLDEMOTE\0" "b\33MOVDIRI\0" \ | 471 | "b\31CLDEMOTE\0" "b\33MOVDIRI\0" \ | |
472 | "b\34MOVDIR64B\0" "b\36SGXLC\0" | 472 | "b\34MOVDIR64B\0" "b\36SGXLC\0" | |
473 | 473 | |||
474 | /* %edx */ | 474 | /* %edx */ | |
475 | #define CPUID_SEF_AVX512_4VNNIW __BIT(2) | 475 | #define CPUID_SEF_AVX512_4VNNIW __BIT(2) | |
476 | #define CPUID_SEF_AVX512_4FMAPS __BIT(3) | 476 | #define CPUID_SEF_AVX512_4FMAPS __BIT(3) | |
477 | #define CPUID_SEF_FSREP_MOV __BIT(4) /* Fast Short REP MOV */ | 477 | #define CPUID_SEF_FSREP_MOV __BIT(4) /* Fast Short REP MOV */ | |
478 | #define CPUID_SEF_AVX512_VP2INTERSECT __BIT(8) | |||
478 | #define CPUID_SEF_MD_CLEAR __BIT(10) | 479 | #define CPUID_SEF_MD_CLEAR __BIT(10) | |
479 | #define CPUID_SEF_TSX_FORCE_ABORT __BIT(13) /* MSR_TSX_FORCE_ABORT bit 0 */ | 480 | #define CPUID_SEF_TSX_FORCE_ABORT __BIT(13) /* MSR_TSX_FORCE_ABORT bit 0 */ | |
481 | #define CPUID_SEF_SERIALIZE __BIT(14) | |||
480 | #define CPUID_SEF_HYBRID __BIT(15) /* Hybrid part */ | 482 | #define CPUID_SEF_HYBRID __BIT(15) /* Hybrid part */ | |
483 | #define CPUID_SEF_TSXLDTRK __BIT(16) /* TSX suspend load addr tracking */ | |||
481 | #define CPUID_SEF_CET_IBT __BIT(20) /* CET Indirect Branch Tracking */ | 484 | #define CPUID_SEF_CET_IBT __BIT(20) /* CET Indirect Branch Tracking */ | |
482 | #define CPUID_SEF_IBRS __BIT(26) /* IBRS / IBPB Speculation Control */ | 485 | #define CPUID_SEF_IBRS __BIT(26) /* IBRS / IBPB Speculation Control */ | |
483 | #define CPUID_SEF_STIBP __BIT(27) /* STIBP Speculation Control */ | 486 | #define CPUID_SEF_STIBP __BIT(27) /* STIBP Speculation Control */ | |
484 | #define CPUID_SEF_L1D_FLUSH __BIT(28) /* IA32_FLUSH_CMD MSR */ | 487 | #define CPUID_SEF_L1D_FLUSH __BIT(28) /* IA32_FLUSH_CMD MSR */ | |
485 | #define CPUID_SEF_ARCH_CAP __BIT(29) /* IA32_ARCH_CAPABILITIES */ | 488 | #define CPUID_SEF_ARCH_CAP __BIT(29) /* IA32_ARCH_CAPABILITIES */ | |
486 | #define CPUID_SEF_CORE_CAP __BIT(30) /* IA32_CORE_CAPABILITIES */ | 489 | #define CPUID_SEF_CORE_CAP __BIT(30) /* IA32_CORE_CAPABILITIES */ | |
487 | #define CPUID_SEF_SSBD __BIT(31) /* Speculative Store Bypass Disable */ | 490 | #define CPUID_SEF_SSBD __BIT(31) /* Speculative Store Bypass Disable */ | |
488 | 491 | |||
489 | #define CPUID_SEF_FLAGS2 "\20" \ | 492 | #define CPUID_SEF_FLAGS2 "\20" \ | |
490 | "\3" "AVX512_4VNNIW" "\4" "AVX512_4FMAPS" \ | 493 | "\3" "AVX512_4VNNIW" "\4" "AVX512_4FMAPS" \ | |
491 | "\5" "FSREP_MOV" \ | 494 | "\5" "FSREP_MOV" \ | |
492 | "\13" "MD_CLEAR" \ | 495 | "\11" "VP2INTERSECT" "\13" "MD_CLEAR" \ | |
493 | "\16" "TSX_FORCE_ABORT" "\20" "HYBRID" \ | 496 | "\16TSX_FORCE_ABORT" "\17SERIALIZE" "\20HYBRID" \ | |
497 | "\21" "TSXLDTRK" \ | |||
494 | "\25" "CET_IBT" \ | 498 | "\25" "CET_IBT" \ | |
495 | "\33" "IBRS" "\34" "STIBP" \ | 499 | "\33" "IBRS" "\34" "STIBP" \ | |
496 | "\35" "L1D_FLUSH" "\36" "ARCH_CAP" "\37CORE_CAP" "\40" "SSBD" | 500 | "\35" "L1D_FLUSH" "\36" "ARCH_CAP" "\37CORE_CAP" "\40" "SSBD" | |
497 | 501 | |||
498 | /* | 502 | /* | |
499 | * Intel CPUID Architectural Performance Monitoring Fn0000000a | 503 | * Intel CPUID Architectural Performance Monitoring Fn0000000a | |
500 | * | 504 | * | |
501 | * See also src/usr.sbin/tprof/arch/tprof_x86.c | 505 | * See also src/usr.sbin/tprof/arch/tprof_x86.c | |
502 | */ | 506 | */ | |
503 | 507 | |||
504 | /* %eax */ | 508 | /* %eax */ | |
505 | #define CPUID_PERF_VERSION __BITS(7, 0) /* Version ID */ | 509 | #define CPUID_PERF_VERSION __BITS(7, 0) /* Version ID */ | |
506 | #define CPUID_PERF_NGPPC __BITS(15, 8) /* Num of G.P. perf counter */ | 510 | #define CPUID_PERF_NGPPC __BITS(15, 8) /* Num of G.P. perf counter */ | |
507 | #define CPUID_PERF_NBWGPPC __BITS(23, 16) /* Bit width of G.P. perfcnt */ | 511 | #define CPUID_PERF_NBWGPPC __BITS(23, 16) /* Bit width of G.P. perfcnt */ | |
508 | #define CPUID_PERF_BVECLEN __BITS(31, 24) /* Length of EBX bit vector */ | 512 | #define CPUID_PERF_BVECLEN __BITS(31, 24) /* Length of EBX bit vector */ | |
509 | 513 | |||
510 | #define CPUID_PERF_FLAGS0 "\177\20" \ | 514 | #define CPUID_PERF_FLAGS0 "\177\20" \ | |
511 | "f\0\10VERSION\0" "f\10\10GPCounter\0" \ | 515 | "f\0\10VERSION\0" "f\10\10GPCounter\0" \ | |
512 | "f\20\10GPBitwidth\0" "f\30\10Vectorlen\0" | 516 | "f\20\10GPBitwidth\0" "f\30\10Vectorlen\0" | |
513 | 517 | |||
514 | /* %ebx */ | 518 | /* %ebx */ | |
515 | #define CPUID_PERF_CORECYCL __BIT(0) /* No core cycle */ | 519 | #define CPUID_PERF_CORECYCL __BIT(0) /* No core cycle */ | |
516 | #define CPUID_PERF_INSTRETRY __BIT(1) /* No instruction retried */ | 520 | #define CPUID_PERF_INSTRETRY __BIT(1) /* No instruction retried */ | |
517 | #define CPUID_PERF_REFCYCL __BIT(2) /* No reference cycles */ | 521 | #define CPUID_PERF_REFCYCL __BIT(2) /* No reference cycles */ | |
518 | #define CPUID_PERF_LLCREF __BIT(3) /* No LLCache reference */ | 522 | #define CPUID_PERF_LLCREF __BIT(3) /* No LLCache reference */ | |
519 | #define CPUID_PERF_LLCMISS __BIT(4) /* No LLCache miss */ | 523 | #define CPUID_PERF_LLCMISS __BIT(4) /* No LLCache miss */ | |
520 | #define CPUID_PERF_BRINSRETR __BIT(5) /* No branch inst. retried */ | 524 | #define CPUID_PERF_BRINSRETR __BIT(5) /* No branch inst. retried */ | |
521 | #define CPUID_PERF_BRMISPRRETR __BIT(6) /* No branch mispredict retry */ | 525 | #define CPUID_PERF_BRMISPRRETR __BIT(6) /* No branch mispredict retry */ | |
522 | 526 | |||
523 | #define CPUID_PERF_FLAGS1 "\177\20" \ | 527 | #define CPUID_PERF_FLAGS1 "\177\20" \ | |
524 | "b\0CORECYCL\0" "b\1INSTRETRY\0" "b\2REFCYCL\0" "b\3LLCREF\0" \ | 528 | "b\0CORECYCL\0" "b\1INSTRETRY\0" "b\2REFCYCL\0" "b\3LLCREF\0" \ | |
525 | "b\4LLCMISS\0" "b\5BRINSRETR\0" "b\6BRMISPRRETR\0" | 529 | "b\4LLCMISS\0" "b\5BRINSRETR\0" "b\6BRMISPRRETR\0" | |
526 | 530 | |||
527 | /* %edx */ | 531 | /* %edx */ | |
528 | #define CPUID_PERF_NFFPC __BITS(4, 0) /* Num of fixed-funct perfcnt */ | 532 | #define CPUID_PERF_NFFPC __BITS(4, 0) /* Num of fixed-funct perfcnt */ | |
529 | #define CPUID_PERF_NBWFFPC __BITS(12, 5) /* Bit width of fixed-func pc */ | 533 | #define CPUID_PERF_NBWFFPC __BITS(12, 5) /* Bit width of fixed-func pc */ | |
530 | #define CPUID_PERF_ANYTHREADDEPR __BIT(15) /* Any Thread deprecation */ | 534 | #define CPUID_PERF_ANYTHREADDEPR __BIT(15) /* Any Thread deprecation */ | |
531 | 535 | |||
532 | #define CPUID_PERF_FLAGS3 "\177\20" \ | 536 | #define CPUID_PERF_FLAGS3 "\177\20" \ | |
533 | "f\0\5FixedFunc\0" "f\5\10FFBitwidth\0" "b\17ANYTHREADDEPR\0" | 537 | "f\0\5FixedFunc\0" "f\5\10FFBitwidth\0" "b\17ANYTHREADDEPR\0" | |
534 | 538 | |||
535 | /* | 539 | /* | |
536 | * Intel CPUID Extended Topology Enumeration Fn0000000b | 540 | * Intel CPUID Extended Topology Enumeration Fn0000000b | |
537 | * %ecx == level number | 541 | * %ecx == level number | |
538 | * %eax: See below. | 542 | * %eax: See below. | |
539 | * %ebx: Number of logical processors at this level. | 543 | * %ebx: Number of logical processors at this level. | |
540 | * %ecx: See below. | 544 | * %ecx: See below. | |
541 | * %edx: x2APIC ID of the current logical processor. | 545 | * %edx: x2APIC ID of the current logical processor. | |
542 | */ | 546 | */ | |
543 | /* %eax */ | 547 | /* %eax */ | |
544 | #define CPUID_TOP_SHIFTNUM __BITS(4, 0) /* Topology ID shift value */ | 548 | #define CPUID_TOP_SHIFTNUM __BITS(4, 0) /* Topology ID shift value */ | |
545 | /* %ecx */ | 549 | /* %ecx */ | |
546 | #define CPUID_TOP_LVLNUM __BITS(7, 0) /* Level number */ | 550 | #define CPUID_TOP_LVLNUM __BITS(7, 0) /* Level number */ | |
547 | #define CPUID_TOP_LVLTYPE __BITS(15, 8) /* Level type */ | 551 | #define CPUID_TOP_LVLTYPE __BITS(15, 8) /* Level type */ | |
548 | #define CPUID_TOP_LVLTYPE_INVAL 0 /* Invalid */ | 552 | #define CPUID_TOP_LVLTYPE_INVAL 0 /* Invalid */ | |
549 | #define CPUID_TOP_LVLTYPE_SMT 1 /* SMT */ | 553 | #define CPUID_TOP_LVLTYPE_SMT 1 /* SMT */ | |
550 | #define CPUID_TOP_LVLTYPE_CORE 2 /* Core */ | 554 | #define CPUID_TOP_LVLTYPE_CORE 2 /* Core */ | |
551 | 555 | |||
552 | /* | 556 | /* | |
553 | * Intel/AMD CPUID Processor extended state Enumeration Fn0000000d | 557 | * Intel/AMD CPUID Processor extended state Enumeration Fn0000000d | |
554 | * | 558 | * | |
555 | * %ecx == 0: supported features info: | 559 | * %ecx == 0: supported features info: | |
556 | * %eax: Valid bits of lower 32bits of XCR0 | 560 | * %eax: Valid bits of lower 32bits of XCR0 | |
557 | * %ebx: Maximum save area size for features enabled in XCR0 | 561 | * %ebx: Maximum save area size for features enabled in XCR0 | |
558 | * %ecx: Maximum save area size for all cpu features | 562 | * %ecx: Maximum save area size for all cpu features | |
559 | * %edx: Valid bits of upper 32bits of XCR0 | 563 | * %edx: Valid bits of upper 32bits of XCR0 | |
560 | * | 564 | * | |
561 | * %ecx == 1: | 565 | * %ecx == 1: | |
562 | * %eax: Bit 0 => xsaveopt instruction available (sandy bridge onwards) | 566 | * %eax: Bit 0 => xsaveopt instruction available (sandy bridge onwards) | |
563 | * %ebx: Save area size for features enabled by XCR0 | IA32_XSS | 567 | * %ebx: Save area size for features enabled by XCR0 | IA32_XSS | |
564 | * %ecx: Valid bits of lower 32bits of IA32_XSS | 568 | * %ecx: Valid bits of lower 32bits of IA32_XSS | |
565 | * %edx: Valid bits of upper 32bits of IA32_XSS | 569 | * %edx: Valid bits of upper 32bits of IA32_XSS | |
566 | * | 570 | * | |
567 | * %ecx >= 2: Save area details for XCR0 bit n | 571 | * %ecx >= 2: Save area details for XCR0 bit n | |
568 | * %eax: size of save area for this feature | 572 | * %eax: size of save area for this feature | |
569 | * %ebx: offset of save area for this feature | 573 | * %ebx: offset of save area for this feature | |
570 | * %ecx, %edx: reserved | 574 | * %ecx, %edx: reserved | |
571 | * All of %eax, %ebx, %ecx and %edx are zero for unsupported features. | 575 | * All of %eax, %ebx, %ecx and %edx are zero for unsupported features. | |
572 | */ | 576 | */ | |
573 | 577 | |||
574 | /* %ecx=1 %eax */ | 578 | /* %ecx=1 %eax */ | |
575 | #define CPUID_PES1_XSAVEOPT 0x00000001 /* xsaveopt instruction */ | 579 | #define CPUID_PES1_XSAVEOPT 0x00000001 /* xsaveopt instruction */ | |
576 | #define CPUID_PES1_XSAVEC 0x00000002 /* xsavec & compacted XRSTOR */ | 580 | #define CPUID_PES1_XSAVEC 0x00000002 /* xsavec & compacted XRSTOR */ | |
577 | #define CPUID_PES1_XGETBV 0x00000004 /* xgetbv with ECX = 1 */ | 581 | #define CPUID_PES1_XGETBV 0x00000004 /* xgetbv with ECX = 1 */ | |
578 | #define CPUID_PES1_XSAVES 0x00000008 /* xsaves/xrstors, IA32_XSS */ | 582 | #define CPUID_PES1_XSAVES 0x00000008 /* xsaves/xrstors, IA32_XSS */ | |
579 | 583 | |||
580 | #define CPUID_PES1_FLAGS "\20" \ | 584 | #define CPUID_PES1_FLAGS "\20" \ | |
581 | "\1" "XSAVEOPT" "\2" "XSAVEC" "\3" "XGETBV" "\4" "XSAVES" | 585 | "\1" "XSAVEOPT" "\2" "XSAVEC" "\3" "XGETBV" "\4" "XSAVES" | |
582 | 586 | |||
583 | /* | 587 | /* | |
584 | * Intel Deterministic Address Translation Parameter Leaf | 588 | * Intel Deterministic Address Translation Parameter Leaf | |
585 | * Fn0000_0018 | 589 | * Fn0000_0018 | |
586 | */ | 590 | */ | |
587 | 591 | |||
588 | /* %ecx=0 %eax __BITS(31, 0): the maximum input value of supported sub-leaf */ | 592 | /* %ecx=0 %eax __BITS(31, 0): the maximum input value of supported sub-leaf */ | |
589 | 593 | |||
590 | /* %ebx */ | 594 | /* %ebx */ | |
591 | #define CPUID_DATP_PGSIZE __BITS(3, 0) /* page size */ | 595 | #define CPUID_DATP_PGSIZE __BITS(3, 0) /* page size */ | |
592 | #define CPUID_DATP_PGSIZE_4KB __BIT(0) /* 4KB page support */ | 596 | #define CPUID_DATP_PGSIZE_4KB __BIT(0) /* 4KB page support */ | |
593 | #define CPUID_DATP_PGSIZE_2MB __BIT(1) /* 2MB page support */ | 597 | #define CPUID_DATP_PGSIZE_2MB __BIT(1) /* 2MB page support */ | |
594 | #define CPUID_DATP_PGSIZE_4MB __BIT(2) /* 4MB page support */ | 598 | #define CPUID_DATP_PGSIZE_4MB __BIT(2) /* 4MB page support */ | |
595 | #define CPUID_DATP_PGSIZE_1GB __BIT(3) /* 1GB page support */ | 599 | #define CPUID_DATP_PGSIZE_1GB __BIT(3) /* 1GB page support */ | |
596 | #define CPUID_DATP_PARTITIONING __BITS(10, 8) /* Partitioning */ | 600 | #define CPUID_DATP_PARTITIONING __BITS(10, 8) /* Partitioning */ | |
597 | #define CPUID_DATP_WAYS __BITS(31, 16) /* Ways of associativity */ | 601 | #define CPUID_DATP_WAYS __BITS(31, 16) /* Ways of associativity */ | |
598 | 602 | |||
599 | /* Number of sets: %ecx */ | 603 | /* Number of sets: %ecx */ | |
600 | 604 | |||
601 | /* %edx */ | 605 | /* %edx */ | |
602 | #define CPUID_DATP_TCTYPE __BITS(4, 0) /* Translation Cache type */ | 606 | #define CPUID_DATP_TCTYPE __BITS(4, 0) /* Translation Cache type */ | |
603 | #define CPUID_DATP_TCTYPE_N 0 /* NULL (not valid) */ | 607 | #define CPUID_DATP_TCTYPE_N 0 /* NULL (not valid) */ | |
604 | #define CPUID_DATP_TCTYPE_D 1 /* Data TLB */ | 608 | #define CPUID_DATP_TCTYPE_D 1 /* Data TLB */ | |
605 | #define CPUID_DATP_TCTYPE_I 2 /* Instruction TLB */ | 609 | #define CPUID_DATP_TCTYPE_I 2 /* Instruction TLB */ | |
606 | #define CPUID_DATP_TCTYPE_U 3 /* Unified TLB */ | 610 | #define CPUID_DATP_TCTYPE_U 3 /* Unified TLB */ | |
607 | #define CPUID_DATP_TCLEVEL __BITS(7, 5) /* TLB level (start at 1) */ | 611 | #define CPUID_DATP_TCLEVEL __BITS(7, 5) /* TLB level (start at 1) */ | |
608 | #define CPUID_DATP_FULLASSOC __BIT(8) /* Full associative */ | 612 | #define CPUID_DATP_FULLASSOC __BIT(8) /* Full associative */ | |
609 | #define CPUID_DATP_SHAREING __BITS(25, 14) /* shareing */ | 613 | #define CPUID_DATP_SHAREING __BITS(25, 14) /* shareing */ | |
610 | 614 | |||
611 | 615 | |||
612 | /* Intel Fn80000001 extended features - %edx */ | 616 | /* Intel Fn80000001 extended features - %edx */ | |
613 | #define CPUID_SYSCALL 0x00000800 /* SYSCALL/SYSRET */ | 617 | #define CPUID_SYSCALL 0x00000800 /* SYSCALL/SYSRET */ | |
614 | #define CPUID_XD 0x00100000 /* Execute Disable (like CPUID_NOX) */ | 618 | #define CPUID_XD 0x00100000 /* Execute Disable (like CPUID_NOX) */ | |
615 | #define CPUID_P1GB 0x04000000 /* 1GB Large Page Support */ | 619 | #define CPUID_P1GB 0x04000000 /* 1GB Large Page Support */ | |
616 | #define CPUID_RDTSCP 0x08000000 /* Read TSC Pair Instruction */ | 620 | #define CPUID_RDTSCP 0x08000000 /* Read TSC Pair Instruction */ | |
617 | #define CPUID_EM64T 0x20000000 /* Intel EM64T */ | 621 | #define CPUID_EM64T 0x20000000 /* Intel EM64T */ | |
618 | 622 | |||
619 | #define CPUID_INTEL_EXT_FLAGS "\20" \ | 623 | #define CPUID_INTEL_EXT_FLAGS "\20" \ | |
620 | "\14" "SYSCALL/SYSRET" "\25" "XD" "\33" "P1GB" \ | 624 | "\14" "SYSCALL/SYSRET" "\25" "XD" "\33" "P1GB" \ | |
621 | "\34" "RDTSCP" "\36" "EM64T" | 625 | "\34" "RDTSCP" "\36" "EM64T" | |
622 | 626 | |||
623 | /* Intel Fn80000001 extended features - %ecx */ | 627 | /* Intel Fn80000001 extended features - %ecx */ | |
624 | #define CPUID_LAHF 0x00000001 /* LAHF/SAHF in IA-32e mode, 64bit sub*/ | 628 | #define CPUID_LAHF 0x00000001 /* LAHF/SAHF in IA-32e mode, 64bit sub*/ | |
625 | /* 0x00000020 */ /* LZCNT. Same as AMD's CPUID_LZCNT */ | 629 | /* 0x00000020 */ /* LZCNT. Same as AMD's CPUID_LZCNT */ | |
626 | #define CPUID_PREFETCHW 0x00000100 /* PREFETCHW */ | 630 | #define CPUID_PREFETCHW 0x00000100 /* PREFETCHW */ | |
627 | 631 | |||
628 | #define CPUID_INTEL_FLAGS4 "\20" \ | 632 | #define CPUID_INTEL_FLAGS4 "\20" \ | |
629 | "\1" "LAHF" "\02" "B01" "\03" "B02" \ | 633 | "\1" "LAHF" "\02" "B01" "\03" "B02" \ | |
630 | "\06" "LZCNT" \ | 634 | "\06" "LZCNT" \ | |
631 | "\11" "PREFETCHW" | 635 | "\11" "PREFETCHW" | |
632 | 636 | |||
633 | 637 | |||
634 | /* AMD/VIA Fn80000001 extended features - %edx */ | 638 | /* AMD/VIA Fn80000001 extended features - %edx */ | |
635 | /* CPUID_SYSCALL SYSCALL/SYSRET */ | 639 | /* CPUID_SYSCALL SYSCALL/SYSRET */ | |
636 | #define CPUID_MPC 0x00080000 /* Multiprocessing Capable */ | 640 | #define CPUID_MPC 0x00080000 /* Multiprocessing Capable */ | |
637 | #define CPUID_NOX 0x00100000 /* No Execute Page Protection */ | 641 | #define CPUID_NOX 0x00100000 /* No Execute Page Protection */ | |
638 | #define CPUID_MMXX 0x00400000 /* AMD MMX Extensions */ | 642 | #define CPUID_MMXX 0x00400000 /* AMD MMX Extensions */ | |
639 | /* CPUID_MMX MMX supported */ | 643 | /* CPUID_MMX MMX supported */ | |
640 | /* CPUID_FXSR fast FP/MMX save/restore */ | 644 | /* CPUID_FXSR fast FP/MMX save/restore */ | |
641 | #define CPUID_FFXSR 0x02000000 /* FXSAVE/FXSTOR Extensions */ | 645 | #define CPUID_FFXSR 0x02000000 /* FXSAVE/FXSTOR Extensions */ | |
642 | /* CPUID_P1GB 1GB Large Page Support */ | 646 | /* CPUID_P1GB 1GB Large Page Support */ | |
643 | /* CPUID_RDTSCP Read TSC Pair Instruction */ | 647 | /* CPUID_RDTSCP Read TSC Pair Instruction */ | |
644 | /* CPUID_EM64T Long mode */ | 648 | /* CPUID_EM64T Long mode */ | |
645 | #define CPUID_3DNOW2 0x40000000 /* 3DNow! Instruction Extension */ | 649 | #define CPUID_3DNOW2 0x40000000 /* 3DNow! Instruction Extension */ | |
646 | #define CPUID_3DNOW 0x80000000 /* 3DNow! Instructions */ | 650 | #define CPUID_3DNOW 0x80000000 /* 3DNow! Instructions */ | |
647 | 651 | |||
648 | #define CPUID_EXT_FLAGS "\20" \ | 652 | #define CPUID_EXT_FLAGS "\20" \ | |
649 | "\14" "SYSCALL/SYSRET" \ | 653 | "\14" "SYSCALL/SYSRET" \ | |
650 | "\24" "MPC" \ | 654 | "\24" "MPC" \ | |
651 | "\25" "NOX" "\27" "MMXX" "\30" "MMX" \ | 655 | "\25" "NOX" "\27" "MMXX" "\30" "MMX" \ | |
652 | "\31" "FXSR" "\32" "FFXSR" "\33" "P1GB" "\34" "RDTSCP" \ | 656 | "\31" "FXSR" "\32" "FFXSR" "\33" "P1GB" "\34" "RDTSCP" \ | |
653 | "\36" "LONG" "\37" "3DNOW2" "\40" "3DNOW" | 657 | "\36" "LONG" "\37" "3DNOW2" "\40" "3DNOW" | |
654 | 658 | |||
655 | /* AMD Fn8000_0001 extended features - %ecx */ | 659 | /* AMD Fn8000_0001 extended features - %ecx */ | |
656 | /* CPUID_LAHF LAHF/SAHF instruction */ | 660 | /* CPUID_LAHF LAHF/SAHF instruction */ | |
657 | #define CPUID_CMPLEGACY 0x00000002 /* Compare Legacy */ | 661 | #define CPUID_CMPLEGACY 0x00000002 /* Compare Legacy */ | |
658 | #define CPUID_SVM 0x00000004 /* Secure Virtual Machine */ | 662 | #define CPUID_SVM 0x00000004 /* Secure Virtual Machine */ | |
659 | #define CPUID_EAPIC 0x00000008 /* Extended APIC space */ | 663 | #define CPUID_EAPIC 0x00000008 /* Extended APIC space */ | |
660 | #define CPUID_ALTMOVCR0 0x00000010 /* Lock Mov Cr0 */ | 664 | #define CPUID_ALTMOVCR0 0x00000010 /* Lock Mov Cr0 */ | |
661 | #define CPUID_LZCNT 0x00000020 /* LZCNT instruction */ | 665 | #define CPUID_LZCNT 0x00000020 /* LZCNT instruction */ | |
662 | #define CPUID_SSE4A 0x00000040 /* SSE4A instruction set */ | 666 | #define CPUID_SSE4A 0x00000040 /* SSE4A instruction set */ | |
663 | #define CPUID_MISALIGNSSE 0x00000080 /* Misaligned SSE */ | 667 | #define CPUID_MISALIGNSSE 0x00000080 /* Misaligned SSE */ | |
664 | #define CPUID_3DNOWPF 0x00000100 /* 3DNow Prefetch */ | 668 | #define CPUID_3DNOWPF 0x00000100 /* 3DNow Prefetch */ | |
665 | #define CPUID_OSVW 0x00000200 /* OS visible workarounds */ | 669 | #define CPUID_OSVW 0x00000200 /* OS visible workarounds */ | |
666 | #define CPUID_IBS 0x00000400 /* Instruction Based Sampling */ | 670 | #define CPUID_IBS 0x00000400 /* Instruction Based Sampling */ | |
667 | #define CPUID_XOP 0x00000800 /* XOP instruction set */ | 671 | #define CPUID_XOP 0x00000800 /* XOP instruction set */ | |
668 | #define CPUID_SKINIT 0x00001000 /* SKINIT */ | 672 | #define CPUID_SKINIT 0x00001000 /* SKINIT */ | |
669 | #define CPUID_WDT 0x00002000 /* watchdog timer support */ | 673 | #define CPUID_WDT 0x00002000 /* watchdog timer support */ | |
670 | #define CPUID_LWP 0x00008000 /* Light Weight Profiling */ | 674 | #define CPUID_LWP 0x00008000 /* Light Weight Profiling */ | |
671 | #define CPUID_FMA4 0x00010000 /* FMA4 instructions */ | 675 | #define CPUID_FMA4 0x00010000 /* FMA4 instructions */ | |
672 | #define CPUID_TCE 0x00020000 /* Translation cache Extension */ | 676 | #define CPUID_TCE 0x00020000 /* Translation cache Extension */ | |
673 | #define CPUID_NODEID 0x00080000 /* NodeID MSR available*/ | 677 | #define CPUID_NODEID 0x00080000 /* NodeID MSR available*/ | |
674 | #define CPUID_TBM 0x00200000 /* TBM instructions */ | 678 | #define CPUID_TBM 0x00200000 /* TBM instructions */ | |
675 | #define CPUID_TOPOEXT 0x00400000 /* cpuid Topology Extension */ | 679 | #define CPUID_TOPOEXT 0x00400000 /* cpuid Topology Extension */ | |
676 | #define CPUID_PCEC 0x00800000 /* Perf Ctr Ext Core */ | 680 | #define CPUID_PCEC 0x00800000 /* Perf Ctr Ext Core */ | |
677 | #define CPUID_PCENB 0x01000000 /* Perf Ctr Ext NB */ | 681 | #define CPUID_PCENB 0x01000000 /* Perf Ctr Ext NB */ | |
678 | #define CPUID_SPM 0x02000000 /* Stream Perf Mon */ | 682 | #define CPUID_SPM 0x02000000 /* Stream Perf Mon */ | |
679 | #define CPUID_DBE 0x04000000 /* Data Breakpoint Extension */ | 683 | #define CPUID_DBE 0x04000000 /* Data Breakpoint Extension */ | |
680 | #define CPUID_PTSC 0x08000000 /* PerfTsc */ | 684 | #define CPUID_PTSC 0x08000000 /* PerfTsc */ | |
681 | #define CPUID_L2IPERFC 0x10000000 /* L2I performance counter Extension */ | 685 | #define CPUID_L2IPERFC 0x10000000 /* L2I performance counter Extension */ | |
682 | #define CPUID_MWAITX 0x20000000 /* MWAITX/MONITORX support */ | 686 | #define CPUID_MWAITX 0x20000000 /* MWAITX/MONITORX support */ | |
683 | 687 | |||
684 | #define CPUID_AMD_FLAGS4 "\20" \ | 688 | #define CPUID_AMD_FLAGS4 "\20" \ | |
685 | "\1" "LAHF" "\2" "CMPLEGACY" "\3" "SVM" "\4" "EAPIC" \ | 689 | "\1" "LAHF" "\2" "CMPLEGACY" "\3" "SVM" "\4" "EAPIC" \ | |
686 | "\5" "ALTMOVCR0" "\6" "LZCNT" "\7" "SSE4A" "\10" "MISALIGNSSE" \ | 690 | "\5" "ALTMOVCR0" "\6" "LZCNT" "\7" "SSE4A" "\10" "MISALIGNSSE" \ | |
687 | "\11" "3DNOWPREFETCH" \ | 691 | "\11" "3DNOWPREFETCH" \ | |
688 | "\12" "OSVW" "\13" "IBS" "\14" "XOP" \ | 692 | "\12" "OSVW" "\13" "IBS" "\14" "XOP" \ | |
689 | "\15" "SKINIT" "\16" "WDT" "\17" "B14" "\20" "LWP" \ | 693 | "\15" "SKINIT" "\16" "WDT" "\17" "B14" "\20" "LWP" \ | |
690 | "\21" "FMA4" "\22" "TCE" "\23" "B18" "\24" "NodeID" \ | 694 | "\21" "FMA4" "\22" "TCE" "\23" "B18" "\24" "NodeID" \ | |
691 | "\25" "B20" "\26" "TBM" "\27" "TopoExt" "\30" "PCExtC" \ | 695 | "\25" "B20" "\26" "TBM" "\27" "TopoExt" "\30" "PCExtC" \ | |
692 | "\31" "PCExtNB" "\32" "StrmPM" "\33" "DBExt" "\34" "PerfTsc" \ | 696 | "\31" "PCExtNB" "\32" "StrmPM" "\33" "DBExt" "\34" "PerfTsc" \ | |
693 | "\35" "L2IPERFC" "\36" "MWAITX" "\37" "B30" "\40" "B31" | 697 | "\35" "L2IPERFC" "\36" "MWAITX" "\37" "B30" "\40" "B31" | |
694 | 698 | |||
695 | /* | 699 | /* | |
696 | * AMD Advanced Power Management | 700 | * Advanced Power Management | |
697 | * CPUID Fn8000_0007 %edx | 701 | * CPUID Fn8000_0007 %edx | |
702 | * | |||
703 | * Only ITSC is for both Intel and AMD. Others are only for AMD. | |||
698 | */ | 704 | */ | |
699 | #define CPUID_APM_TS 0x00000001 /* Temperature Sensor */ | 705 | #define CPUID_APM_TS 0x00000001 /* Temperature Sensor */ | |
700 | #define CPUID_APM_FID 0x00000002 /* Frequency ID control */ | 706 | #define CPUID_APM_FID 0x00000002 /* Frequency ID control */ | |
701 | #define CPUID_APM_VID 0x00000004 /* Voltage ID control */ | 707 | #define CPUID_APM_VID 0x00000004 /* Voltage ID control */ | |
702 | #define CPUID_APM_TTP 0x00000008 /* THERMTRIP (PCI F3xE4 register) */ | 708 | #define CPUID_APM_TTP 0x00000008 /* THERMTRIP (PCI F3xE4 register) */ | |
703 | #define CPUID_APM_HTC 0x00000010 /* Hardware thermal control (HTC) */ | 709 | #define CPUID_APM_HTC 0x00000010 /* Hardware thermal control (HTC) */ | |
704 | #define CPUID_APM_STC 0x00000020 /* Software thermal control (STC) */ | 710 | #define CPUID_APM_STC 0x00000020 /* Software thermal control (STC) */ | |
705 | #define CPUID_APM_100 0x00000040 /* 100MHz multiplier control */ | 711 | #define CPUID_APM_100 0x00000040 /* 100MHz multiplier control */ | |
706 | #define CPUID_APM_HWP 0x00000080 /* HW P-State control */ | 712 | #define CPUID_APM_HWP 0x00000080 /* HW P-State control */ | |
707 | #define CPUID_APM_TSC 0x00000100 /* TSC invariant */ | 713 | #define CPUID_APM_ITSC 0x00000100 /* invariant TSC */ | |
708 | #define CPUID_APM_CPB 0x00000200 /* Core performance boost */ | 714 | #define CPUID_APM_CPB 0x00000200 /* Core performance boost */ | |
709 | #define CPUID_APM_EFF 0x00000400 /* Effective Frequency (read-only) */ | 715 | #define CPUID_APM_EFF 0x00000400 /* Effective Frequency (read-only) */ | |
710 | #define CPUID_APM_PROCFI 0x00000800 /* Proc Feedback Interface */ | 716 | #define CPUID_APM_PROCFI 0x00000800 /* Proc Feedback Interface */ | |
711 | #define CPUID_APM_PROCPR 0x00001000 /* Proc Power Reporting */ | 717 | #define CPUID_APM_PROCPR 0x00001000 /* Proc Power Reporting */ | |
712 | #define CPUID_APM_CONNSTBY 0x00002000 /* Connected Standby */ | 718 | #define CPUID_APM_CONNSTBY 0x00002000 /* Connected Standby */ | |
713 | #define CPUID_APM_RAPL 0x00004000 /* Running Average Power Limit */ | 719 | #define CPUID_APM_RAPL 0x00004000 /* Running Average Power Limit */ | |
714 | 720 | |||
715 | #define CPUID_APM_FLAGS "\20" \ | 721 | #define CPUID_APM_FLAGS "\20" \ | |
716 | "\1" "TS" "\2" "FID" "\3" "VID" "\4" "TTP" \ | 722 | "\1" "TS" "\2" "FID" "\3" "VID" "\4" "TTP" \ | |
717 | "\5" "HTC" "\6" "STC" "\7" "100" "\10" "HWP" \ | 723 | "\5" "HTC" "\6" "STC" "\7" "100" "\10" "HWP" \ | |
718 | "\11" "TSC" "\12" "CPB" "\13" "EffFreq" "\14" "PROCFI" \ | 724 | "\11" "ITSC" "\12" "CPB" "\13" "EffFreq" "\14" "PROCFI" \ | |
719 | "\15" "PROCPR" "\16" "CONNSTBY" "\17" "RAPL" | 725 | "\15" "PROCPR" "\16" "CONNSTBY" "\17" "RAPL" | |
720 | 726 | |||
721 | /* | 727 | /* | |
722 | * AMD Processor Capacity Parameters and Extended Features | 728 | * AMD Processor Capacity Parameters and Extended Features | |
723 | * CPUID Fn8000_0008 | 729 | * CPUID Fn8000_0008 | |
724 | * %eax: Long Mode Size Identifiers | 730 | * %eax: Long Mode Size Identifiers | |
725 | * %ebx: Extended Feature Identifiers | 731 | * %ebx: Extended Feature Identifiers | |
726 | * %ecx: Size Identifiers | 732 | * %ecx: Size Identifiers | |
727 | */ | 733 | */ | |
728 | 734 | |||
729 | /* %ebx */ | 735 | /* %ebx */ | |
730 | #define CPUID_CAPEX_CLZERO __BIT(0) /* CLZERO instruction */ | 736 | #define CPUID_CAPEX_CLZERO __BIT(0) /* CLZERO instruction */ | |
731 | #define CPUID_CAPEX_IRPERF __BIT(1) /* InstRetCntMsr */ | 737 | #define CPUID_CAPEX_IRPERF __BIT(1) /* InstRetCntMsr */ | |
732 | #define CPUID_CAPEX_XSAVEERPTR __BIT(2) /* RstrFpErrPtrs by XRSTOR */ | 738 | #define CPUID_CAPEX_XSAVEERPTR __BIT(2) /* RstrFpErrPtrs by XRSTOR */ | |
733 | #define CPUID_CAPEX_RDPRU __BIT(4) /* RDPRU instruction */ | 739 | #define CPUID_CAPEX_RDPRU __BIT(4) /* RDPRU instruction */ | |
734 | #define CPUID_CAPEX_MCOMMIT __BIT(8) /* MCOMMIT instruction */ | 740 | #define CPUID_CAPEX_MCOMMIT __BIT(8) /* MCOMMIT instruction */ | |
735 | #define CPUID_CAPEX_WBNOINVD __BIT(9) /* WBNOINVD instruction */ | 741 | #define CPUID_CAPEX_WBNOINVD __BIT(9) /* WBNOINVD instruction */ | |
736 | #define CPUID_CAPEX_IBPB __BIT(12) /* Speculation Control IBPB */ | 742 | #define CPUID_CAPEX_IBPB __BIT(12) /* Speculation Control IBPB */ | |
737 | #define CPUID_CAPEX_IBRS __BIT(14) /* Speculation Control IBRS */ | 743 | #define CPUID_CAPEX_IBRS __BIT(14) /* Speculation Control IBRS */ | |
738 | #define CPUID_CAPEX_STIBP __BIT(15) /* Speculation Control STIBP */ | 744 | #define CPUID_CAPEX_STIBP __BIT(15) /* Speculation Control STIBP */ | |
739 | #define CPUID_CAPEX_IBRS_ALWAYSON __BIT(16) /* IBRS always on mode */ | 745 | #define CPUID_CAPEX_IBRS_ALWAYSON __BIT(16) /* IBRS always on mode */ | |
740 | #define CPUID_CAPEX_STIBP_ALWAYSON __BIT(17) /* STIBP always on mode */ | 746 | #define CPUID_CAPEX_STIBP_ALWAYSON __BIT(17) /* STIBP always on mode */ | |
741 | #define CPUID_CAPEX_PREFER_IBRS __BIT(18) /* IBRS preferred */ | 747 | #define CPUID_CAPEX_PREFER_IBRS __BIT(18) /* IBRS preferred */ | |
742 | #define CPUID_CAPEX_SSBD __BIT(24) /* Speculation Control SSBD */ | 748 | #define CPUID_CAPEX_SSBD __BIT(24) /* Speculation Control SSBD */ | |
743 | #define CPUID_CAPEX_VIRT_SSBD __BIT(25) /* Virt Spec Control SSBD */ | 749 | #define CPUID_CAPEX_VIRT_SSBD __BIT(25) /* Virt Spec Control SSBD */ | |
744 | #define CPUID_CAPEX_SSB_NO __BIT(26) /* SSBD not required */ | 750 | #define CPUID_CAPEX_SSB_NO __BIT(26) /* SSBD not required */ | |
745 | 751 | |||
746 | #define CPUID_CAPEX_FLAGS "\20" \ | 752 | #define CPUID_CAPEX_FLAGS "\20" \ | |
747 | "\1CLZERO" "\2IRPERF" "\3XSAVEERPTR" \ | 753 | "\1CLZERO" "\2IRPERF" "\3XSAVEERPTR" \ | |
748 | "\5RDPRU" "\7B6" \ | 754 | "\5RDPRU" "\7B6" \ | |
749 | "\11MCOMMIT" "\12WBNOINVD" "\13B10" \ | 755 | "\11MCOMMIT" "\12WBNOINVD" "\13B10" \ | |
750 | "\15IBPB" "\16B13" "\17IBRS" "\20STIBP" \ | 756 | "\15IBPB" "\16B13" "\17IBRS" "\20STIBP" \ | |
751 | "\21IBRS_ALWAYSON" "\22STIBP_ALWAYSON" "\23PREFER_IBRS" "\24B19" \ | 757 | "\21IBRS_ALWAYSON" "\22STIBP_ALWAYSON" "\23PREFER_IBRS" "\24B19" \ | |
752 | "\31SSBD" "\32VIRT_SSBD" "\33SSB_NO" | 758 | "\31SSBD" "\32VIRT_SSBD" "\33SSB_NO" | |
753 | 759 | |||
754 | /* AMD Fn8000_000a %edx features (SVM features) */ | 760 | /* AMD Fn8000_000a %edx features (SVM features) */ | |
755 | #define CPUID_AMD_SVM_NP 0x00000001 | 761 | #define CPUID_AMD_SVM_NP 0x00000001 | |
756 | #define CPUID_AMD_SVM_LbrVirt 0x00000002 | 762 | #define CPUID_AMD_SVM_LbrVirt 0x00000002 | |
757 | #define CPUID_AMD_SVM_SVML 0x00000004 | 763 | #define CPUID_AMD_SVM_SVML 0x00000004 | |
758 | #define CPUID_AMD_SVM_NRIPS 0x00000008 | 764 | #define CPUID_AMD_SVM_NRIPS 0x00000008 | |
759 | #define CPUID_AMD_SVM_TSCRateCtrl 0x00000010 | 765 | #define CPUID_AMD_SVM_TSCRateCtrl 0x00000010 | |
760 | #define CPUID_AMD_SVM_VMCBCleanBits 0x00000020 | 766 | #define CPUID_AMD_SVM_VMCBCleanBits 0x00000020 | |
761 | #define CPUID_AMD_SVM_FlushByASID 0x00000040 | 767 | #define CPUID_AMD_SVM_FlushByASID 0x00000040 | |
762 | #define CPUID_AMD_SVM_DecodeAssist 0x00000080 | 768 | #define CPUID_AMD_SVM_DecodeAssist 0x00000080 | |
763 | #define CPUID_AMD_SVM_PauseFilter 0x00000400 | 769 | #define CPUID_AMD_SVM_PauseFilter 0x00000400 | |
764 | #define CPUID_AMD_SVM_PFThreshold 0x00001000 /* PAUSE filter threshold */ | 770 | #define CPUID_AMD_SVM_PFThreshold 0x00001000 /* PAUSE filter threshold */ | |
765 | #define CPUID_AMD_SVM_AVIC 0x00002000 /* AMD Virtual intr. ctrl */ | 771 | #define CPUID_AMD_SVM_AVIC 0x00002000 /* AMD Virtual intr. ctrl */ | |
766 | #define CPUID_AMD_SVM_V_VMSAVE_VMLOAD 0x00008000 /* Virtual VM{SAVE/LOAD} */ | 772 | #define CPUID_AMD_SVM_V_VMSAVE_VMLOAD 0x00008000 /* Virtual VM{SAVE/LOAD} */ | |
767 | #define CPUID_AMD_SVM_vGIF 0x00010000 /* Virtualized GIF */ | 773 | #define CPUID_AMD_SVM_vGIF 0x00010000 /* Virtualized GIF */ | |
768 | #define CPUID_AMD_SVM_GMET 0x00020000 | 774 | #define CPUID_AMD_SVM_GMET 0x00020000 | |
769 | #define CPUID_AMD_SVM_FLAGS "\20" \ | 775 | #define CPUID_AMD_SVM_FLAGS "\20" \ | |
770 | "\1" "NP" "\2" "LbrVirt" "\3" "SVML" "\4" "NRIPS" \ | 776 | "\1" "NP" "\2" "LbrVirt" "\3" "SVML" "\4" "NRIPS" \ | |
771 | "\5" "TSCRate" "\6" "VMCBCleanBits" \ | 777 | "\5" "TSCRate" "\6" "VMCBCleanBits" \ | |
772 | "\7" "FlushByASID" "\10" "DecodeAssist" \ | 778 | "\7" "FlushByASID" "\10" "DecodeAssist" \ | |
773 | "\11" "B08" "\12" "B09" "\13" "PauseFilter" "\14" "B11" \ | 779 | "\11" "B08" "\12" "B09" "\13" "PauseFilter" "\14" "B11" \ | |
774 | "\15" "PFThreshold" "\16" "AVIC" "\17" "B14" \ | 780 | "\15" "PFThreshold" "\16" "AVIC" "\17" "B14" \ | |
775 | "\20" "V_VMSAVE_VMLOAD" \ | 781 | "\20" "V_VMSAVE_VMLOAD" \ | |
776 | "\21" "VGIF" "\22" "GMET" \ | 782 | "\21" "VGIF" "\22" "GMET" \ | |
777 | "\25" "B20" | 783 | "\25" "B20" | |
778 | 784 | |||
779 | /* | 785 | /* | |
780 | * AMD Fn8000_0001d Cache Topology Information. | 786 | * AMD Fn8000_0001d Cache Topology Information. | |
781 | * It's almost the same as Intel Deterministic Cache Parameter Leaf(0x04) | 787 | * It's almost the same as Intel Deterministic Cache Parameter Leaf(0x04) | |
782 | * except the following: | 788 | * except the following: | |
783 | * No Cores/package (%eax bit 31..26) | 789 | * No Cores/package (%eax bit 31..26) | |
784 | * No Complex cache indexing (%edx bit 2) | 790 | * No Complex cache indexing (%edx bit 2) | |
785 | */ | 791 | */ | |
786 | 792 | |||
787 | /* | 793 | /* | |
788 | * AMD Fn8000_0001f Encrypted Memory Capabilities. | 794 | * AMD Fn8000_0001f Encrypted Memory Capabilities. | |
789 | * %eax: flags | 795 | * %eax: flags | |
790 | * %ebx: 5-0: Cbit Position | 796 | * %ebx: 5-0: Cbit Position | |
791 | * 11-6: PhysAddrReduction | 797 | * 11-6: PhysAddrReduction | |
792 | * %ecx: 31-0: NumEncryptedGuests | 798 | * %ecx: 31-0: NumEncryptedGuests | |
793 | * %edx: 31-0: MinSevNoEsAsid | 799 | * %edx: 31-0: MinSevNoEsAsid | |
794 | */ | 800 | */ | |
795 | #define CPUID_AMD_ENCMEM_SME __BIT(0) /* Secure Memory Encryption */ | 801 | #define CPUID_AMD_ENCMEM_SME __BIT(0) /* Secure Memory Encryption */ | |
796 | #define CPUID_AMD_ENCMEM_SEV __BIT(1) /* Secure Encrypted Virtualiz. */ | 802 | #define CPUID_AMD_ENCMEM_SEV __BIT(1) /* Secure Encrypted Virtualiz. */ | |
797 | #define CPUID_AMD_ENCMEM_PGFLMSR __BIT(2) /* Page Flush MSR */ | 803 | #define CPUID_AMD_ENCMEM_PGFLMSR __BIT(2) /* Page Flush MSR */ | |
798 | #define CPUID_AMD_ENCMEM_SEVES __BIT(3) /* SEV Encrypted State */ | 804 | #define CPUID_AMD_ENCMEM_SEVES __BIT(3) /* SEV Encrypted State */ | |
799 | #define CPUID_AMD_ENCMEM_VTE __BIT(16) /* Virtual Transparent Encryption */ | 805 | #define CPUID_AMD_ENCMEM_VTE __BIT(16) /* Virtual Transparent Encryption */ | |
800 | 806 | |||
801 | #define CPUID_AMD_ENCMEM_FLAGS "\20" \ | 807 | #define CPUID_AMD_ENCMEM_FLAGS "\20" \ | |
802 | "\1" "SME" "\2" "SEV" "\3" "PageFlushMsr" "\4" "SEV-ES" \ | 808 | "\1" "SME" "\2" "SEV" "\3" "PageFlushMsr" "\4" "SEV-ES" \ | |
803 | "\21" "VTE" | 809 | "\21" "VTE" | |
804 | 810 | |||
805 | /* | 811 | /* | |
806 | * Centaur Extended Feature flags | 812 | * Centaur Extended Feature flags | |
807 | */ | 813 | */ | |
808 | #define CPUID_VIA_HAS_RNG 0x00000004 /* Random number generator */ | 814 | #define CPUID_VIA_HAS_RNG 0x00000004 /* Random number generator */ | |
809 | #define CPUID_VIA_DO_RNG 0x00000008 | 815 | #define CPUID_VIA_DO_RNG 0x00000008 | |
810 | #define CPUID_VIA_HAS_ACE 0x00000040 /* AES Encryption */ | 816 | #define CPUID_VIA_HAS_ACE 0x00000040 /* AES Encryption */ | |
811 | #define CPUID_VIA_DO_ACE 0x00000080 | 817 | #define CPUID_VIA_DO_ACE 0x00000080 | |
812 | #define CPUID_VIA_HAS_ACE2 0x00000100 /* AES+CTR instructions */ | 818 | #define CPUID_VIA_HAS_ACE2 0x00000100 /* AES+CTR instructions */ | |
813 | #define CPUID_VIA_DO_ACE2 0x00000200 | 819 | #define CPUID_VIA_DO_ACE2 0x00000200 | |
814 | #define CPUID_VIA_HAS_PHE 0x00000400 /* SHA1+SHA256 HMAC */ | 820 | #define CPUID_VIA_HAS_PHE 0x00000400 /* SHA1+SHA256 HMAC */ | |
815 | #define CPUID_VIA_DO_PHE 0x00000800 | 821 | #define CPUID_VIA_DO_PHE 0x00000800 | |
816 | #define CPUID_VIA_HAS_PMM 0x00001000 /* RSA Instructions */ | 822 | #define CPUID_VIA_HAS_PMM 0x00001000 /* RSA Instructions */ | |
817 | #define CPUID_VIA_DO_PMM 0x00002000 | 823 | #define CPUID_VIA_DO_PMM 0x00002000 | |
818 | 824 | |||
819 | #define CPUID_FLAGS_PADLOCK "\20" \ | 825 | #define CPUID_FLAGS_PADLOCK "\20" \ | |
820 | "\3" "RNG" "\7" "AES" "\11" "AES/CTR" "\13" "SHA1/SHA256" \ | 826 | "\3" "RNG" "\7" "AES" "\11" "AES/CTR" "\13" "SHA1/SHA256" \ | |
821 | "\15" "RSA" | 827 | "\15" "RSA" | |
822 | 828 | |||
823 | /* | 829 | /* | |
824 | * Model-Specific Registers | 830 | * Model-Specific Registers | |
825 | */ | 831 | */ | |
826 | #define MSR_TSC 0x010 | 832 | #define MSR_TSC 0x010 | |
827 | #define MSR_IA32_PLATFORM_ID 0x017 | 833 | #define MSR_IA32_PLATFORM_ID 0x017 | |
828 | #define MSR_APICBASE 0x01b | 834 | #define MSR_APICBASE 0x01b | |
829 | #define APICBASE_BSP 0x00000100 /* boot processor */ | 835 | #define APICBASE_BSP 0x00000100 /* boot processor */ | |
830 | #define APICBASE_EXTD 0x00000400 /* x2APIC mode */ | 836 | #define APICBASE_EXTD 0x00000400 /* x2APIC mode */ | |
831 | #define APICBASE_EN 0x00000800 /* software enable */ | 837 | #define APICBASE_EN 0x00000800 /* software enable */ | |
832 | /* | 838 | /* | |
833 | * APICBASE_PHYSADDR is actually variable-sized on some CPUs. But we're | 839 | * APICBASE_PHYSADDR is actually variable-sized on some CPUs. But we're | |
834 | * only interested in the initial value, which is guaranteed to fit the | 840 | * only interested in the initial value, which is guaranteed to fit the | |
835 | * first 32 bits. So this macro is fine. | 841 | * first 32 bits. So this macro is fine. | |
836 | */ | 842 | */ | |
837 | #define APICBASE_PHYSADDR 0xfffff000 /* physical address */ | 843 | #define APICBASE_PHYSADDR 0xfffff000 /* physical address */ | |
838 | #define MSR_EBL_CR_POWERON 0x02a | 844 | #define MSR_EBL_CR_POWERON 0x02a | |
839 | #define MSR_EBC_FREQUENCY_ID 0x02c /* PIV only */ | 845 | #define MSR_EBC_FREQUENCY_ID 0x02c /* PIV only */ | |
840 | #define MSR_IA32_SPEC_CTRL 0x048 | 846 | #define MSR_IA32_SPEC_CTRL 0x048 | |
841 | #define IA32_SPEC_CTRL_IBRS 0x01 | 847 | #define IA32_SPEC_CTRL_IBRS 0x01 | |
842 | #define IA32_SPEC_CTRL_STIBP 0x02 | 848 | #define IA32_SPEC_CTRL_STIBP 0x02 | |
843 | #define IA32_SPEC_CTRL_SSBD 0x04 | 849 | #define IA32_SPEC_CTRL_SSBD 0x04 | |
844 | #define MSR_IA32_PRED_CMD 0x049 | 850 | #define MSR_IA32_PRED_CMD 0x049 | |
845 | #define IA32_PRED_CMD_IBPB 0x01 | 851 | #define IA32_PRED_CMD_IBPB 0x01 | |
846 | #define MSR_BIOS_UPDT_TRIG 0x079 | 852 | #define MSR_BIOS_UPDT_TRIG 0x079 | |
847 | #define MSR_BIOS_SIGN 0x08b | 853 | #define MSR_BIOS_SIGN 0x08b | |
848 | #define MSR_PERFCTR0 0x0c1 | 854 | #define MSR_PERFCTR0 0x0c1 | |
849 | #define MSR_PERFCTR1 0x0c2 | 855 | #define MSR_PERFCTR1 0x0c2 | |
850 | #define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ | 856 | #define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ | |
851 | #define MSR_MPERF 0x0e7 | 857 | #define MSR_MPERF 0x0e7 | |
852 | #define MSR_APERF 0x0e8 | 858 | #define MSR_APERF 0x0e8 | |
853 | #define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ | 859 | #define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ | |
854 | #define MSR_MTRRcap 0x0fe | 860 | #define MSR_MTRRcap 0x0fe | |
855 | #define MSR_IA32_ARCH_CAPABILITIES 0x10a | 861 | #define MSR_IA32_ARCH_CAPABILITIES 0x10a | |
856 | #define IA32_ARCH_RDCL_NO 0x01 | 862 | #define IA32_ARCH_RDCL_NO 0x01 | |
857 | #define IA32_ARCH_IBRS_ALL 0x02 | 863 | #define IA32_ARCH_IBRS_ALL 0x02 | |
858 | #define IA32_ARCH_RSBA 0x04 | 864 | #define IA32_ARCH_RSBA 0x04 | |
859 | #define IA32_ARCH_SKIP_L1DFL_VMENTRY 0x08 | 865 | #define IA32_ARCH_SKIP_L1DFL_VMENTRY 0x08 | |
860 | #define IA32_ARCH_SSB_NO 0x10 | 866 | #define IA32_ARCH_SSB_NO 0x10 | |
861 | #define IA32_ARCH_MDS_NO 0x20 | 867 | #define IA32_ARCH_MDS_NO 0x20 | |
862 | #define IA32_ARCH_TSX_CTRL 0x80 | 868 | #define IA32_ARCH_TSX_CTRL 0x80 | |
863 | #define IA32_ARCH_TAA_NO 0x100 | 869 | #define IA32_ARCH_TAA_NO 0x100 | |
864 | #define MSR_IA32_FLUSH_CMD 0x10b | 870 | #define MSR_IA32_FLUSH_CMD 0x10b | |
865 | #define IA32_FLUSH_CMD_L1D_FLUSH 0x01 | 871 | #define IA32_FLUSH_CMD_L1D_FLUSH 0x01 | |
866 | #define MSR_TSX_FORCE_ABORT 0x10f | 872 | #define MSR_TSX_FORCE_ABORT 0x10f | |
867 | #define MSR_IA32_TSX_CTRL 0x122 | 873 | #define MSR_IA32_TSX_CTRL 0x122 | |
868 | #define IA32_TSX_CTRL_RTM_DISABLE __BIT(0) | 874 | #define IA32_TSX_CTRL_RTM_DISABLE __BIT(0) | |
869 | #define IA32_TSX_CTRL_TSX_CPUID_CLEAR __BIT(1) | 875 | #define IA32_TSX_CTRL_TSX_CPUID_CLEAR __BIT(1) | |
870 | #define MSR_SYSENTER_CS 0x174 /* PII+ only */ | 876 | #define MSR_SYSENTER_CS 0x174 /* PII+ only */ | |
871 | #define MSR_SYSENTER_ESP 0x175 /* PII+ only */ | 877 | #define MSR_SYSENTER_ESP 0x175 /* PII+ only */ | |
872 | #define MSR_SYSENTER_EIP 0x176 /* PII+ only */ | 878 | #define MSR_SYSENTER_EIP 0x176 /* PII+ only */ | |
873 | #define MSR_MCG_CAP 0x179 | 879 | #define MSR_MCG_CAP 0x179 | |
874 | #define MSR_MCG_STATUS 0x17a | 880 | #define MSR_MCG_STATUS 0x17a | |
875 | #define MSR_MCG_CTL 0x17b | 881 | #define MSR_MCG_CTL 0x17b | |
876 | #define MSR_EVNTSEL0 0x186 | 882 | #define MSR_EVNTSEL0 0x186 | |
877 | #define MSR_EVNTSEL1 0x187 | 883 | #define MSR_EVNTSEL1 0x187 | |
878 | #define MSR_PERF_STATUS 0x198 /* Pentium M */ | 884 | #define MSR_PERF_STATUS 0x198 /* Pentium M */ | |
879 | #define MSR_PERF_CTL 0x199 /* Pentium M */ | 885 | #define MSR_PERF_CTL 0x199 /* Pentium M */ | |
880 | #define MSR_THERM_CONTROL 0x19a | 886 | #define MSR_THERM_CONTROL 0x19a | |
881 | #define MSR_THERM_INTERRUPT 0x19b | 887 | #define MSR_THERM_INTERRUPT 0x19b | |
882 | #define MSR_THERM_STATUS 0x19c | 888 | #define MSR_THERM_STATUS 0x19c | |
883 | #define MSR_THERM2_CTL 0x19d /* Pentium M */ | 889 | #define MSR_THERM2_CTL 0x19d /* Pentium M */ | |
884 | #define MSR_MISC_ENABLE 0x1a0 | 890 | #define MSR_MISC_ENABLE 0x1a0 | |
885 | #define IA32_MISC_FAST_STR_EN __BIT(0) | 891 | #define IA32_MISC_FAST_STR_EN __BIT(0) | |
886 | #define IA32_MISC_ATCC_EN __BIT(3) | 892 | #define IA32_MISC_ATCC_EN __BIT(3) | |
887 | #define IA32_MISC_PERFMON_EN __BIT(7) | 893 | #define IA32_MISC_PERFMON_EN __BIT(7) | |
888 | #define IA32_MISC_BTS_UNAVAIL __BIT(11) | 894 | #define IA32_MISC_BTS_UNAVAIL __BIT(11) | |
889 | #define IA32_MISC_PEBS_UNAVAIL __BIT(12) | 895 | #define IA32_MISC_PEBS_UNAVAIL __BIT(12) | |
890 | #define IA32_MISC_EISST_EN __BIT(16) | 896 | #define IA32_MISC_EISST_EN __BIT(16) | |
891 | #define IA32_MISC_MWAIT_EN __BIT(18) | 897 | #define IA32_MISC_MWAIT_EN __BIT(18) | |
892 | #define IA32_MISC_LIMIT_CPUID __BIT(22) | 898 | #define IA32_MISC_LIMIT_CPUID __BIT(22) | |
893 | #define IA32_MISC_XTPR_DIS __BIT(23) | 899 | #define IA32_MISC_XTPR_DIS __BIT(23) | |
894 | #define IA32_MISC_XD_DIS __BIT(34) | 900 | #define IA32_MISC_XD_DIS __BIT(34) | |
895 | #define MSR_TEMPERATURE_TARGET 0x1a2 | 901 | #define MSR_TEMPERATURE_TARGET 0x1a2 | |
896 | #define MSR_DEBUGCTLMSR 0x1d9 | 902 | #define MSR_DEBUGCTLMSR 0x1d9 | |
897 | #define MSR_LASTBRANCHFROMIP 0x1db | 903 | #define MSR_LASTBRANCHFROMIP 0x1db | |
898 | #define MSR_LASTBRANCHTOIP 0x1dc | 904 | #define MSR_LASTBRANCHTOIP 0x1dc | |
899 | #define MSR_LASTINTFROMIP 0x1dd | 905 | #define MSR_LASTINTFROMIP 0x1dd | |
900 | #define MSR_LASTINTTOIP 0x1de | 906 | #define MSR_LASTINTTOIP 0x1de | |
901 | #define MSR_ROB_CR_BKUPTMPDR6 0x1e0 | 907 | #define MSR_ROB_CR_BKUPTMPDR6 0x1e0 | |
902 | #define MSR_MTRRphysBase0 0x200 | 908 | #define MSR_MTRRphysBase0 0x200 | |
903 | #define MSR_MTRRphysMask0 0x201 | 909 | #define MSR_MTRRphysMask0 0x201 | |
904 | #define MSR_MTRRphysBase1 0x202 | 910 | #define MSR_MTRRphysBase1 0x202 | |
905 | #define MSR_MTRRphysMask1 0x203 | 911 | #define MSR_MTRRphysMask1 0x203 | |
906 | #define MSR_MTRRphysBase2 0x204 | 912 | #define MSR_MTRRphysBase2 0x204 | |
907 | #define MSR_MTRRphysMask2 0x205 | 913 | #define MSR_MTRRphysMask2 0x205 | |
908 | #define MSR_MTRRphysBase3 0x206 | 914 | #define MSR_MTRRphysBase3 0x206 | |
909 | #define MSR_MTRRphysMask3 0x207 | 915 | #define MSR_MTRRphysMask3 0x207 | |
910 | #define MSR_MTRRphysBase4 0x208 | 916 | #define MSR_MTRRphysBase4 0x208 | |
911 | #define MSR_MTRRphysMask4 0x209 | 917 | #define MSR_MTRRphysMask4 0x209 | |
912 | #define MSR_MTRRphysBase5 0x20a | 918 | #define MSR_MTRRphysBase5 0x20a | |
913 | #define MSR_MTRRphysMask5 0x20b | 919 | #define MSR_MTRRphysMask5 0x20b | |
914 | #define MSR_MTRRphysBase6 0x20c | 920 | #define MSR_MTRRphysBase6 0x20c | |
915 | #define MSR_MTRRphysMask6 0x20d | 921 | #define MSR_MTRRphysMask6 0x20d | |
916 | #define MSR_MTRRphysBase7 0x20e | 922 | #define MSR_MTRRphysBase7 0x20e | |
917 | #define MSR_MTRRphysMask7 0x20f | 923 | #define MSR_MTRRphysMask7 0x20f | |
918 | #define MSR_MTRRphysBase8 0x210 | 924 | #define MSR_MTRRphysBase8 0x210 | |
919 | #define MSR_MTRRphysMask8 0x211 | 925 | #define MSR_MTRRphysMask8 0x211 | |
920 | #define MSR_MTRRphysBase9 0x212 | 926 | #define MSR_MTRRphysBase9 0x212 | |
921 | #define MSR_MTRRphysMask9 0x213 | 927 | #define MSR_MTRRphysMask9 0x213 | |
922 | #define MSR_MTRRphysBase10 0x214 | 928 | #define MSR_MTRRphysBase10 0x214 | |
923 | #define MSR_MTRRphysMask10 0x215 | 929 | #define MSR_MTRRphysMask10 0x215 | |
924 | #define MSR_MTRRphysBase11 0x216 | 930 | #define MSR_MTRRphysBase11 0x216 | |
925 | #define MSR_MTRRphysMask11 0x217 | 931 | #define MSR_MTRRphysMask11 0x217 | |
926 | #define MSR_MTRRphysBase12 0x218 | 932 | #define MSR_MTRRphysBase12 0x218 | |
927 | #define MSR_MTRRphysMask12 0x219 | 933 | #define MSR_MTRRphysMask12 0x219 | |
928 | #define MSR_MTRRphysBase13 0x21a | 934 | #define MSR_MTRRphysBase13 0x21a | |
929 | #define MSR_MTRRphysMask13 0x21b | 935 | #define MSR_MTRRphysMask13 0x21b | |
930 | #define MSR_MTRRphysBase14 0x21c | 936 | #define MSR_MTRRphysBase14 0x21c | |
931 | #define MSR_MTRRphysMask14 0x21d | 937 | #define MSR_MTRRphysMask14 0x21d | |
932 | #define MSR_MTRRphysBase15 0x21e | 938 | #define MSR_MTRRphysBase15 0x21e | |
933 | #define MSR_MTRRphysMask15 0x21f | 939 | #define MSR_MTRRphysMask15 0x21f | |
934 | #define MSR_MTRRfix64K_00000 0x250 | 940 | #define MSR_MTRRfix64K_00000 0x250 | |
935 | #define MSR_MTRRfix16K_80000 0x258 | 941 | #define MSR_MTRRfix16K_80000 0x258 | |
936 | #define MSR_MTRRfix16K_A0000 0x259 | 942 | #define MSR_MTRRfix16K_A0000 0x259 | |
937 | #define MSR_MTRRfix4K_C0000 0x268 | 943 | #define MSR_MTRRfix4K_C0000 0x268 | |
938 | #define MSR_MTRRfix4K_C8000 0x269 | 944 | #define MSR_MTRRfix4K_C8000 0x269 | |
939 | #define MSR_MTRRfix4K_D0000 0x26a | 945 | #define MSR_MTRRfix4K_D0000 0x26a | |
940 | #define MSR_MTRRfix4K_D8000 0x26b | 946 | #define MSR_MTRRfix4K_D8000 0x26b | |
941 | #define MSR_MTRRfix4K_E0000 0x26c | 947 | #define MSR_MTRRfix4K_E0000 0x26c | |
942 | #define MSR_MTRRfix4K_E8000 0x26d | 948 | #define MSR_MTRRfix4K_E8000 0x26d | |
943 | #define MSR_MTRRfix4K_F0000 0x26e | 949 | #define MSR_MTRRfix4K_F0000 0x26e | |
944 | #define MSR_MTRRfix4K_F8000 0x26f | 950 | #define MSR_MTRRfix4K_F8000 0x26f | |
945 | #define MSR_CR_PAT 0x277 | 951 | #define MSR_CR_PAT 0x277 | |
946 | #define MSR_MTRRdefType 0x2ff | 952 | #define MSR_MTRRdefType 0x2ff | |
947 | #define MSR_MC0_CTL 0x400 | 953 | #define MSR_MC0_CTL 0x400 | |
948 | #define MSR_MC0_STATUS 0x401 | 954 | #define MSR_MC0_STATUS 0x401 | |
949 | #define MSR_MC0_ADDR 0x402 | 955 | #define MSR_MC0_ADDR 0x402 | |
950 | #define MSR_MC0_MISC 0x403 | 956 | #define MSR_MC0_MISC 0x403 | |
951 | #define MSR_MC1_CTL 0x404 | 957 | #define MSR_MC1_CTL 0x404 | |
952 | #define MSR_MC1_STATUS 0x405 | 958 | #define MSR_MC1_STATUS 0x405 | |
953 | #define MSR_MC1_ADDR 0x406 | 959 | #define MSR_MC1_ADDR 0x406 | |
954 | #define MSR_MC1_MISC 0x407 | 960 | #define MSR_MC1_MISC 0x407 | |
955 | #define MSR_MC2_CTL 0x408 | 961 | #define MSR_MC2_CTL 0x408 | |
956 | #define MSR_MC2_STATUS 0x409 | 962 | #define MSR_MC2_STATUS 0x409 | |
957 | #define MSR_MC2_ADDR 0x40a | 963 | #define MSR_MC2_ADDR 0x40a | |
958 | #define MSR_MC2_MISC 0x40b | 964 | #define MSR_MC2_MISC 0x40b | |
959 | #define MSR_MC3_CTL 0x40c | 965 | #define MSR_MC3_CTL 0x40c | |
960 | #define MSR_MC3_STATUS 0x40d | 966 | #define MSR_MC3_STATUS 0x40d | |
961 | #define MSR_MC3_ADDR 0x40e | 967 | #define MSR_MC3_ADDR 0x40e | |
962 | #define MSR_MC3_MISC 0x40f | 968 | #define MSR_MC3_MISC 0x40f | |
963 | #define MSR_MC4_CTL 0x410 | 969 | #define MSR_MC4_CTL 0x410 | |
964 | #define MSR_MC4_STATUS 0x411 | 970 | #define MSR_MC4_STATUS 0x411 | |
965 | #define MSR_MC4_ADDR 0x412 | 971 | #define MSR_MC4_ADDR 0x412 | |
966 | #define MSR_MC4_MISC 0x413 | 972 | #define MSR_MC4_MISC 0x413 | |
967 | /* 0x480 - 0x490 VMX */ | 973 | /* 0x480 - 0x490 VMX */ | |
968 | #define MSR_X2APIC_BASE 0x800 /* 0x800 - 0xBFF */ | 974 | #define MSR_X2APIC_BASE 0x800 /* 0x800 - 0xBFF */ | |
969 | #define MSR_X2APIC_ID 0x002 /* x2APIC ID. (RO) */ | 975 | #define MSR_X2APIC_ID 0x002 /* x2APIC ID. (RO) */ | |
970 | #define MSR_X2APIC_VERS 0x003 /* Version. (RO) */ | 976 | #define MSR_X2APIC_VERS 0x003 /* Version. (RO) */ | |
971 | #define MSR_X2APIC_TPRI 0x008 /* Task Prio. (RW) */ | 977 | #define MSR_X2APIC_TPRI 0x008 /* Task Prio. (RW) */ | |
972 | #define MSR_X2APIC_PPRI 0x00a /* Processor prio. (RO) */ | 978 | #define MSR_X2APIC_PPRI 0x00a /* Processor prio. (RO) */ | |
973 | #define MSR_X2APIC_EOI 0x00b /* End Int. (W) */ | 979 | #define MSR_X2APIC_EOI 0x00b /* End Int. (W) */ | |
974 | #define MSR_X2APIC_LDR 0x00d /* Logical dest. (RO) */ | 980 | #define MSR_X2APIC_LDR 0x00d /* Logical dest. (RO) */ | |
975 | #define MSR_X2APIC_SVR 0x00f /* Spurious intvec (RW) */ | 981 | #define MSR_X2APIC_SVR 0x00f /* Spurious intvec (RW) */ | |
976 | #define MSR_X2APIC_ISR 0x010 /* In-Service Status (RO) */ | 982 | #define MSR_X2APIC_ISR 0x010 /* In-Service Status (RO) */ | |
977 | #define MSR_X2APIC_TMR 0x018 /* Trigger Mode (RO) */ | 983 | #define MSR_X2APIC_TMR 0x018 /* Trigger Mode (RO) */ | |
978 | #define MSR_X2APIC_IRR 0x020 /* Interrupt Req (RO) */ | 984 | #define MSR_X2APIC_IRR 0x020 /* Interrupt Req (RO) */ | |
979 | #define MSR_X2APIC_ESR 0x028 /* Err status. (RW) */ | 985 | #define MSR_X2APIC_ESR 0x028 /* Err status. (RW) */ | |
980 | #define MSR_X2APIC_LVT_CMCI 0x02f /* LVT CMCI (RW) */ | 986 | #define MSR_X2APIC_LVT_CMCI 0x02f /* LVT CMCI (RW) */ | |
981 | #define MSR_X2APIC_ICRLO 0x030 /* Int. cmd. (RW64) */ | 987 | #define MSR_X2APIC_ICRLO 0x030 /* Int. cmd. (RW64) */ | |
982 | #define MSR_X2APIC_LVTT 0x032 /* Loc.vec.(timer) (RW) */ | 988 | #define MSR_X2APIC_LVTT 0x032 /* Loc.vec.(timer) (RW) */ | |
983 | #define MSR_X2APIC_TMINT 0x033 /* Loc.vec (Thermal) (RW) */ | 989 | #define MSR_X2APIC_TMINT 0x033 /* Loc.vec (Thermal) (RW) */ | |
984 | #define MSR_X2APIC_PCINT 0x034 /* Loc.vec (Perf Mon) (RW) */ | 990 | #define MSR_X2APIC_PCINT 0x034 /* Loc.vec (Perf Mon) (RW) */ | |
985 | #define MSR_X2APIC_LVINT0 0x035 /* Loc.vec (LINT0) (RW) */ | 991 | #define MSR_X2APIC_LVINT0 0x035 /* Loc.vec (LINT0) (RW) */ | |
986 | #define MSR_X2APIC_LVINT1 0x036 /* Loc.vec (LINT1) (RW) */ | 992 | #define MSR_X2APIC_LVINT1 0x036 /* Loc.vec (LINT1) (RW) */ | |
987 | #define MSR_X2APIC_LVERR 0x037 /* Loc.vec (ERROR) (RW) */ | 993 | #define MSR_X2APIC_LVERR 0x037 /* Loc.vec (ERROR) (RW) */ | |
988 | #define MSR_X2APIC_ICR_TIMER 0x038 /* Initial count (RW) */ | 994 | #define MSR_X2APIC_ICR_TIMER 0x038 /* Initial count (RW) */ | |
989 | #define MSR_X2APIC_CCR_TIMER 0x039 /* Current count (RO) */ | 995 | #define MSR_X2APIC_CCR_TIMER 0x039 /* Current count (RO) */ | |
990 | #define MSR_X2APIC_DCR_TIMER 0x03e /* Divisor config (RW) */ | 996 | #define MSR_X2APIC_DCR_TIMER 0x03e /* Divisor config (RW) */ | |
991 | #define MSR_X2APIC_SELF_IPI 0x03f /* SELF IPI (W) */ | 997 | #define MSR_X2APIC_SELF_IPI 0x03f /* SELF IPI (W) */ | |
992 | 998 | |||
993 | /* | 999 | /* | |
994 | * VIA "Nehemiah" MSRs | 1000 | * VIA "Nehemiah" MSRs | |
995 | */ | 1001 | */ | |
996 | #define MSR_VIA_RNG 0x0000110b | 1002 | #define MSR_VIA_RNG 0x0000110b | |
997 | #define MSR_VIA_RNG_ENABLE 0x00000040 | 1003 | #define MSR_VIA_RNG_ENABLE 0x00000040 | |
998 | #define MSR_VIA_RNG_NOISE_MASK 0x00000300 | 1004 | #define MSR_VIA_RNG_NOISE_MASK 0x00000300 | |
999 | #define MSR_VIA_RNG_NOISE_A 0x00000000 | 1005 | #define MSR_VIA_RNG_NOISE_A 0x00000000 | |
1000 | #define MSR_VIA_RNG_NOISE_B 0x00000100 | 1006 | #define MSR_VIA_RNG_NOISE_B 0x00000100 | |
1001 | #define MSR_VIA_RNG_2NOISE 0x00000300 | 1007 | #define MSR_VIA_RNG_2NOISE 0x00000300 | |
1002 | #define MSR_VIA_ACE 0x00001107 | 1008 | #define MSR_VIA_ACE 0x00001107 | |
1003 | #define VIA_ACE_ALTINST 0x00000001 | 1009 | #define VIA_ACE_ALTINST 0x00000001 | |
1004 | #define VIA_ACE_ECX8 0x00000002 | 1010 | #define VIA_ACE_ECX8 0x00000002 | |
1005 | #define VIA_ACE_ENABLE 0x10000000 | 1011 | #define VIA_ACE_ENABLE 0x10000000 | |
1006 | 1012 | |||
1007 | /* | 1013 | /* | |
1008 | * VIA "Eden" MSRs | 1014 | * VIA "Eden" MSRs | |
1009 | */ | 1015 | */ | |
1010 | #define MSR_VIA_FCR MSR_VIA_ACE | 1016 | #define MSR_VIA_FCR MSR_VIA_ACE | |
1011 | 1017 | |||
1012 | /* | 1018 | /* | |
1013 | * AMD K6/K7 MSRs. | 1019 | * AMD K6/K7 MSRs. | |
1014 | */ | 1020 | */ | |
1015 | #define MSR_K6_UWCCR 0xc0000085 | 1021 | #define MSR_K6_UWCCR 0xc0000085 | |
1016 | #define MSR_K7_EVNTSEL0 0xc0010000 | 1022 | #define MSR_K7_EVNTSEL0 0xc0010000 | |
1017 | #define MSR_K7_EVNTSEL1 0xc0010001 | 1023 | #define MSR_K7_EVNTSEL1 0xc0010001 | |
1018 | #define MSR_K7_EVNTSEL2 0xc0010002 | 1024 | #define MSR_K7_EVNTSEL2 0xc0010002 | |
1019 | #define MSR_K7_EVNTSEL3 0xc0010003 | 1025 | #define MSR_K7_EVNTSEL3 0xc0010003 | |
1020 | #define MSR_K7_PERFCTR0 0xc0010004 | 1026 | #define MSR_K7_PERFCTR0 0xc0010004 | |
1021 | #define MSR_K7_PERFCTR1 0xc0010005 | 1027 | #define MSR_K7_PERFCTR1 0xc0010005 | |
1022 | #define MSR_K7_PERFCTR2 0xc0010006 | 1028 | #define MSR_K7_PERFCTR2 0xc0010006 | |
1023 | #define MSR_K7_PERFCTR3 0xc0010007 | 1029 | #define MSR_K7_PERFCTR3 0xc0010007 | |
1024 | 1030 | |||
1025 | /* | 1031 | /* | |
1026 | * AMD K8 (Opteron) MSRs. | 1032 | * AMD K8 (Opteron) MSRs. | |
1027 | */ | 1033 | */ | |
1028 | #define MSR_SYSCFG 0xc0010010 | 1034 | #define MSR_SYSCFG 0xc0010010 | |
1029 | 1035 | |||
1030 | #define MSR_EFER 0xc0000080 /* Extended feature enable */ | 1036 | #define MSR_EFER 0xc0000080 /* Extended feature enable */ | |
1031 | #define EFER_SCE 0x00000001 /* SYSCALL extension */ | 1037 | #define EFER_SCE 0x00000001 /* SYSCALL extension */ | |
1032 | #define EFER_LME 0x00000100 /* Long Mode Enable */ | 1038 | #define EFER_LME 0x00000100 /* Long Mode Enable */ | |
1033 | #define EFER_LMA 0x00000400 /* Long Mode Active */ | 1039 | #define EFER_LMA 0x00000400 /* Long Mode Active */ | |
1034 | #define EFER_NXE 0x00000800 /* No-Execute Enabled */ | 1040 | #define EFER_NXE 0x00000800 /* No-Execute Enabled */ | |
1035 | #define EFER_SVME 0x00001000 /* Secure Virtual Machine En. */ | 1041 | #define EFER_SVME 0x00001000 /* Secure Virtual Machine En. */ | |
1036 | #define EFER_LMSLE 0x00002000 /* Long Mode Segment Limit E. */ | 1042 | #define EFER_LMSLE 0x00002000 /* Long Mode Segment Limit E. */ | |
1037 | #define EFER_FFXSR 0x00004000 /* Fast FXSAVE/FXRSTOR En. */ | 1043 | #define EFER_FFXSR 0x00004000 /* Fast FXSAVE/FXRSTOR En. */ | |
1038 | #define EFER_TCE 0x00008000 /* Translation Cache Ext. */ | 1044 | #define EFER_TCE 0x00008000 /* Translation Cache Ext. */ | |
1039 | 1045 | |||
1040 | #define MSR_STAR 0xc0000081 /* 32 bit syscall gate addr */ | 1046 | #define MSR_STAR 0xc0000081 /* 32 bit syscall gate addr */ | |
1041 | #define MSR_LSTAR 0xc0000082 /* 64 bit syscall gate addr */ | 1047 | #define MSR_LSTAR 0xc0000082 /* 64 bit syscall gate addr */ | |
1042 | #define MSR_CSTAR 0xc0000083 /* compat syscall gate addr */ | 1048 | #define MSR_CSTAR 0xc0000083 /* compat syscall gate addr */ | |
1043 | #define MSR_SFMASK 0xc0000084 /* flags to clear on syscall */ | 1049 | #define MSR_SFMASK 0xc0000084 /* flags to clear on syscall */ | |
1044 | 1050 | |||
1045 | #define MSR_FSBASE 0xc0000100 /* 64bit offset for fs: */ | 1051 | #define MSR_FSBASE 0xc0000100 /* 64bit offset for fs: */ | |
1046 | #define MSR_GSBASE 0xc0000101 /* 64bit offset for gs: */ | 1052 | #define MSR_GSBASE 0xc0000101 /* 64bit offset for gs: */ | |
1047 | #define MSR_KERNELGSBASE 0xc0000102 /* storage for swapgs ins */ | 1053 | #define MSR_KERNELGSBASE 0xc0000102 /* storage for swapgs ins */ | |
1048 | 1054 | |||
1049 | #define MSR_VMCR 0xc0010114 /* Virtual Machine Control Register */ | 1055 | #define MSR_VMCR 0xc0010114 /* Virtual Machine Control Register */ | |
1050 | #define VMCR_DPD 0x00000001 /* Debug port disable */ | 1056 | #define VMCR_DPD 0x00000001 /* Debug port disable */ | |
1051 | #define VMCR_RINIT 0x00000002 /* intercept init */ | 1057 | #define VMCR_RINIT 0x00000002 /* intercept init */ | |
1052 | #define VMCR_DISA20 0x00000004 /* Disable A20 masking */ | 1058 | #define VMCR_DISA20 0x00000004 /* Disable A20 masking */ | |
1053 | #define VMCR_LOCK 0x00000008 /* SVM Lock */ | 1059 | #define VMCR_LOCK 0x00000008 /* SVM Lock */ | |
1054 | #define VMCR_SVMED 0x00000010 /* SVME Disable */ | 1060 | #define VMCR_SVMED 0x00000010 /* SVME Disable */ | |
1055 | #define MSR_SVMLOCK 0xc0010118 /* SVM Lock key */ | 1061 | #define MSR_SVMLOCK 0xc0010118 /* SVM Lock key */ | |
1056 | 1062 | |||
1057 | /* | 1063 | /* | |
1058 | * These require a 'passcode' for access. See cpufunc.h. | 1064 | * These require a 'passcode' for access. See cpufunc.h. | |
1059 | */ | 1065 | */ | |
1060 | #define MSR_HWCR 0xc0010015 | 1066 | #define MSR_HWCR 0xc0010015 | |
1061 | #define HWCR_TLBCACHEDIS 0x00000008 | 1067 | #define HWCR_TLBCACHEDIS 0x00000008 | |
1062 | #define HWCR_FFDIS 0x00000040 | 1068 | #define HWCR_FFDIS 0x00000040 | |
1063 | 1069 | |||
1064 | #define MSR_NB_CFG 0xc001001f | 1070 | #define MSR_NB_CFG 0xc001001f | |
1065 | #define NB_CFG_DISIOREQLOCK 0x0000000000000008ULL | 1071 | #define NB_CFG_DISIOREQLOCK 0x0000000000000008ULL | |
1066 | #define NB_CFG_DISDATMSK 0x0000001000000000ULL | 1072 | #define NB_CFG_DISDATMSK 0x0000001000000000ULL | |
1067 | #define NB_CFG_INITAPICCPUIDLO (1ULL << 54) | 1073 | #define NB_CFG_INITAPICCPUIDLO (1ULL << 54) | |
1068 | 1074 | |||
1069 | #define MSR_LS_CFG 0xc0011020 | 1075 | #define MSR_LS_CFG 0xc0011020 | |
1070 | #define LS_CFG_ERRATA_1033 __BIT(4) | 1076 | #define LS_CFG_ERRATA_1033 __BIT(4) | |
1071 | #define LS_CFG_ERRATA_793 __BIT(15) | 1077 | #define LS_CFG_ERRATA_793 __BIT(15) | |
1072 | #define LS_CFG_ERRATA_1095 __BIT(57) | 1078 | #define LS_CFG_ERRATA_1095 __BIT(57) | |
1073 | #define LS_CFG_DIS_LS2_SQUISH 0x02000000 | 1079 | #define LS_CFG_DIS_LS2_SQUISH 0x02000000 | |
1074 | #define LS_CFG_DIS_SSB_F15H 0x0040000000000000ULL | 1080 | #define LS_CFG_DIS_SSB_F15H 0x0040000000000000ULL | |
1075 | #define LS_CFG_DIS_SSB_F16H 0x0000000200000000ULL | 1081 | #define LS_CFG_DIS_SSB_F16H 0x0000000200000000ULL | |
1076 | #define LS_CFG_DIS_SSB_F17H 0x0000000000000400ULL | 1082 | #define LS_CFG_DIS_SSB_F17H 0x0000000000000400ULL | |
1077 | 1083 | |||
1078 | #define MSR_IC_CFG 0xc0011021 | 1084 | #define MSR_IC_CFG 0xc0011021 | |
1079 | #define IC_CFG_DIS_SEQ_PREFETCH 0x00000800 | 1085 | #define IC_CFG_DIS_SEQ_PREFETCH 0x00000800 | |
1080 | #define IC_CFG_DIS_IND 0x00004000 | 1086 | #define IC_CFG_DIS_IND 0x00004000 | |
1081 | #define IC_CFG_ERRATA_776 __BIT(26) | 1087 | #define IC_CFG_ERRATA_776 __BIT(26) | |
1082 | 1088 | |||
1083 | #define MSR_DC_CFG 0xc0011022 | 1089 | #define MSR_DC_CFG 0xc0011022 | |
1084 | #define DC_CFG_DIS_CNV_WC_SSO 0x00000008 | 1090 | #define DC_CFG_DIS_CNV_WC_SSO 0x00000008 | |
1085 | #define DC_CFG_DIS_SMC_CHK_BUF 0x00000400 | 1091 | #define DC_CFG_DIS_SMC_CHK_BUF 0x00000400 | |
1086 | #define DC_CFG_ERRATA_261 0x01000000 | 1092 | #define DC_CFG_ERRATA_261 0x01000000 | |
1087 | 1093 | |||
1088 | #define MSR_BU_CFG 0xc0011023 | 1094 | #define MSR_BU_CFG 0xc0011023 | |
1089 | #define BU_CFG_ERRATA_298 0x0000000000000002ULL | 1095 | #define BU_CFG_ERRATA_298 0x0000000000000002ULL | |
1090 | #define BU_CFG_ERRATA_254 0x0000000000200000ULL | 1096 | #define BU_CFG_ERRATA_254 0x0000000000200000ULL | |
1091 | #define BU_CFG_ERRATA_309 0x0000000000800000ULL | 1097 | #define BU_CFG_ERRATA_309 0x0000000000800000ULL | |
1092 | #define BU_CFG_THRL2IDXCMPDIS 0x0000080000000000ULL | 1098 | #define BU_CFG_THRL2IDXCMPDIS 0x0000080000000000ULL | |
1093 | #define BU_CFG_WBPFSMCCHKDIS 0x0000200000000000ULL | 1099 | #define BU_CFG_WBPFSMCCHKDIS 0x0000200000000000ULL | |
1094 | #define BU_CFG_WBENHWSBDIS 0x0001000000000000ULL | 1100 | #define BU_CFG_WBENHWSBDIS 0x0001000000000000ULL | |
1095 | 1101 | |||
1096 | #define MSR_FP_CFG 0xc0011028 | 1102 | #define MSR_FP_CFG 0xc0011028 | |
1097 | #define FP_CFG_ERRATA_1049 __BIT(4) | 1103 | #define FP_CFG_ERRATA_1049 __BIT(4) | |
1098 | 1104 | |||
1099 | #define MSR_DE_CFG 0xc0011029 | 1105 | #define MSR_DE_CFG 0xc0011029 | |
1100 | #define DE_CFG_ERRATA_721 0x00000001 | 1106 | #define DE_CFG_ERRATA_721 0x00000001 | |
1101 | #define DE_CFG_ERRATA_1021 __BIT(13) | 1107 | #define DE_CFG_ERRATA_1021 __BIT(13) | |
1102 | 1108 | |||
1103 | #define MSR_BU_CFG2 0xc001102a | 1109 | #define MSR_BU_CFG2 0xc001102a | |
1104 | #define BU_CFG2_CWPLUS_DIS __BIT(24) | 1110 | #define BU_CFG2_CWPLUS_DIS __BIT(24) | |
1105 | 1111 | |||
1106 | #define MSR_LS_CFG2 0xc001102d | 1112 | #define MSR_LS_CFG2 0xc001102d | |
1107 | #define LS_CFG2_ERRATA_1091 __BIT(34) | 1113 | #define LS_CFG2_ERRATA_1091 __BIT(34) | |
1108 | 1114 | |||
1109 | /* AMD Family10h MSRs */ | 1115 | /* AMD Family10h MSRs */ | |
1110 | #define MSR_OSVW_ID_LENGTH 0xc0010140 | 1116 | #define MSR_OSVW_ID_LENGTH 0xc0010140 | |
1111 | #define MSR_OSVW_STATUS 0xc0010141 | 1117 | #define MSR_OSVW_STATUS 0xc0010141 | |
1112 | #define MSR_UCODE_AMD_PATCHLEVEL 0x0000008b | 1118 | #define MSR_UCODE_AMD_PATCHLEVEL 0x0000008b | |
1113 | #define MSR_UCODE_AMD_PATCHLOADER 0xc0010020 | 1119 | #define MSR_UCODE_AMD_PATCHLOADER 0xc0010020 | |
1114 | 1120 | |||
1115 | /* X86 MSRs */ | 1121 | /* X86 MSRs */ | |
1116 | #define MSR_RDTSCP_AUX 0xc0000103 | 1122 | #define MSR_RDTSCP_AUX 0xc0000103 | |
1117 | 1123 | |||
1118 | /* | 1124 | /* | |
1119 | * Constants related to MTRRs | 1125 | * Constants related to MTRRs | |
1120 | */ | 1126 | */ | |
1121 | #define MTRR_N64K 8 /* numbers of fixed-size entries */ | 1127 | #define MTRR_N64K 8 /* numbers of fixed-size entries */ | |
1122 | #define MTRR_N16K 16 | 1128 | #define MTRR_N16K 16 | |
1123 | #define MTRR_N4K 64 | 1129 | #define MTRR_N4K 64 | |
1124 | 1130 | |||
1125 | /* | 1131 | /* | |
1126 | * the following four 3-byte registers control the non-cacheable regions. | 1132 | * the following four 3-byte registers control the non-cacheable regions. | |
1127 | * These registers must be written as three separate bytes. | 1133 | * These registers must be written as three separate bytes. | |
1128 | * | 1134 | * | |
1129 | * NCRx+0: A31-A24 of starting address | 1135 | * NCRx+0: A31-A24 of starting address | |
1130 | * NCRx+1: A23-A16 of starting address | 1136 | * NCRx+1: A23-A16 of starting address | |
1131 | * NCRx+2: A15-A12 of starting address | NCR_SIZE_xx. | 1137 | * NCRx+2: A15-A12 of starting address | NCR_SIZE_xx. | |
1132 | * | 1138 | * | |
1133 | * The non-cacheable region's starting address must be aligned to the | 1139 | * The non-cacheable region's starting address must be aligned to the | |
1134 | * size indicated by the NCR_SIZE_xx field. | 1140 | * size indicated by the NCR_SIZE_xx field. | |
1135 | */ | 1141 | */ | |
1136 | #define NCR1 0xc4 | 1142 | #define NCR1 0xc4 | |
1137 | #define NCR2 0xc7 | 1143 | #define NCR2 0xc7 | |
1138 | #define NCR3 0xca | 1144 | #define NCR3 0xca | |
1139 | #define NCR4 0xcd | 1145 | #define NCR4 0xcd | |
1140 | 1146 | |||
1141 | #define NCR_SIZE_0K 0 | 1147 | #define NCR_SIZE_0K 0 | |
1142 | #define NCR_SIZE_4K 1 | 1148 | #define NCR_SIZE_4K 1 | |
1143 | #define NCR_SIZE_8K 2 | 1149 | #define NCR_SIZE_8K 2 | |
1144 | #define NCR_SIZE_16K 3 | 1150 | #define NCR_SIZE_16K 3 | |
1145 | #define NCR_SIZE_32K 4 | 1151 | #define NCR_SIZE_32K 4 | |
1146 | #define NCR_SIZE_64K 5 | 1152 | #define NCR_SIZE_64K 5 | |
1147 | #define NCR_SIZE_128K 6 | 1153 | #define NCR_SIZE_128K 6 | |
1148 | #define NCR_SIZE_256K 7 | 1154 | #define NCR_SIZE_256K 7 | |
1149 | #define NCR_SIZE_512K 8 | 1155 | #define NCR_SIZE_512K 8 | |
1150 | #define NCR_SIZE_1M 9 | 1156 | #define NCR_SIZE_1M 9 | |
1151 | #define NCR_SIZE_2M 10 | 1157 | #define NCR_SIZE_2M 10 | |
1152 | #define NCR_SIZE_4M 11 | 1158 | #define NCR_SIZE_4M 11 | |
1153 | #define NCR_SIZE_8M 12 | 1159 | #define NCR_SIZE_8M 12 | |
1154 | #define NCR_SIZE_16M 13 | 1160 | #define NCR_SIZE_16M 13 | |
1155 | #define NCR_SIZE_32M 14 | 1161 | #define NCR_SIZE_32M 14 | |
1156 | #define NCR_SIZE_4G 15 | 1162 | #define NCR_SIZE_4G 15 |
--- src/sys/arch/x86/x86/procfs_machdep.c 2019/10/17 18:56:25 1.33.2.1
+++ src/sys/arch/x86/x86/procfs_machdep.c 2020/04/14 17:15:02 1.33.2.2
@@ -1,524 +1,524 @@ | @@ -1,524 +1,524 @@ | |||
1 | /* $NetBSD: procfs_machdep.c,v 1.33.2.1 2019/10/17 18:56:25 martin Exp $ */ | 1 | /* $NetBSD: procfs_machdep.c,v 1.33.2.2 2020/04/14 17:15:02 martin Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2001 Wasabi Systems, Inc. | 4 | * Copyright (c) 2001 Wasabi Systems, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Written by Frank van der Linden and Jason R. Thorpe for | 7 | * Written by Frank van der Linden and Jason R. Thorpe for | |
8 | * Wasabi Systems, Inc. | 8 | * Wasabi Systems, Inc. | |
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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. All advertising materials mentioning features or use of this software | 18 | * 3. All advertising materials mentioning features or use of this software | |
19 | * must display the following acknowledgement: | 19 | * must display the following acknowledgement: | |
20 | * This product includes software developed for the NetBSD Project by | 20 | * This product includes software developed for the NetBSD Project by | |
21 | * Wasabi Systems, Inc. | 21 | * Wasabi Systems, Inc. | |
22 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse | 22 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse | |
23 | * or promote products derived from this software without specific prior | 23 | * or promote products derived from this software without specific prior | |
24 | * written permission. | 24 | * written permission. | |
25 | * | 25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND | 26 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND | |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC | 29 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC | |
30 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 30 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
36 | * POSSIBILITY OF SUCH DAMAGE. | 36 | * POSSIBILITY OF SUCH DAMAGE. | |
37 | */ | 37 | */ | |
38 | 38 | |||
39 | /* | 39 | /* | |
40 | * NOTE: We simply use the primary CPU's cpuid_level and tsc_freq | 40 | * NOTE: We simply use the primary CPU's cpuid_level and tsc_freq | |
41 | * here. Might want to change this later. | 41 | * here. Might want to change this later. | |
42 | */ | 42 | */ | |
43 | 43 | |||
44 | #include <sys/cdefs.h> | 44 | #include <sys/cdefs.h> | |
45 | __KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.33.2.1 2019/10/17 18:56:25 martin Exp $"); | 45 | __KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.33.2.2 2020/04/14 17:15:02 martin Exp $"); | |
46 | 46 | |||
47 | #include <sys/param.h> | 47 | #include <sys/param.h> | |
48 | #include <sys/systm.h> | 48 | #include <sys/systm.h> | |
49 | #include <sys/mount.h> | 49 | #include <sys/mount.h> | |
50 | #include <sys/stat.h> | 50 | #include <sys/stat.h> | |
51 | #include <sys/vnode.h> | 51 | #include <sys/vnode.h> | |
52 | 52 | |||
53 | #include <miscfs/procfs/procfs.h> | 53 | #include <miscfs/procfs/procfs.h> | |
54 | 54 | |||
55 | #include <machine/cpu.h> | 55 | #include <machine/cpu.h> | |
56 | #include <machine/reg.h> | 56 | #include <machine/reg.h> | |
57 | #include <machine/specialreg.h> | 57 | #include <machine/specialreg.h> | |
58 | #include <x86/cputypes.h> | 58 | #include <x86/cputypes.h> | |
59 | #include <x86/cpuvar.h> | 59 | #include <x86/cpuvar.h> | |
60 | 60 | |||
61 | /* | 61 | /* | |
62 | * The feature table. The order is the same as Linux's | 62 | * The feature table. The order is the same as Linux's | |
63 | * x86/include/asm/cpufeatures.h. | 63 | * x86/include/asm/cpufeatures.h. | |
64 | */ | 64 | */ | |
65 | static const char * const x86_features[][32] = { | 65 | static const char * const x86_features[][32] = { | |
66 | { /* (0) Common: 0x0000001 edx */ | 66 | { /* (0) Common: 0x0000001 edx */ | |
67 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", | 67 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", | |
68 | "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", | 68 | "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", | |
69 | "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", | 69 | "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", | |
70 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"}, | 70 | "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"}, | |
71 | 71 | |||
72 | { /* (1) AMD-defined: 0x80000001 edx */ | 72 | { /* (1) AMD-defined: 0x80000001 edx */ | |
73 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 73 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
74 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, | 74 | NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, | |
75 | NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, | 75 | NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, | |
76 | NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext","3dnow"}, | 76 | NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext","3dnow"}, | |
77 | 77 | |||
78 | { /* (2) Transmeta-defined */ | 78 | { /* (2) Transmeta-defined */ | |
79 | "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, | 79 | "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, | |
80 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 80 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
81 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 81 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
82 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 82 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
83 | 83 | |||
84 | { /* (3) Linux mapping */ | 84 | { /* (3) Linux mapping */ | |
85 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, | 85 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, | |
86 | "constant_tsc", NULL, NULL, | 86 | "constant_tsc", NULL, NULL, | |
87 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 87 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
88 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 88 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
89 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 89 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
90 | 90 | |||
91 | { /* (4) Intel-defined: 0x00000001 ecx */ | 91 | { /* (4) Intel-defined: 0x00000001 ecx */ | |
92 | "pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est", | 92 | "pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est", | |
93 | "tm2", "ssse3", "cid", "sdbg", "fma", "cx16", "xtpr", "pdcm", | 93 | "tm2", "ssse3", "cid", "sdbg", "fma", "cx16", "xtpr", "pdcm", | |
94 | NULL, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt", | 94 | NULL, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt", | |
95 | "tsc_deadline_timer", "aes", "xsave", NULL, | 95 | "tsc_deadline_timer", "aes", "xsave", NULL, | |
96 | "avx", "f16c", "rdrand", "hypervisor"}, | 96 | "avx", "f16c", "rdrand", "hypervisor"}, | |
97 | 97 | |||
98 | { /* (5) VIA/Cyrix/Centaur-defined */ | 98 | { /* (5) VIA/Cyrix/Centaur-defined */ | |
99 | NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", | 99 | NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", | |
100 | "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, | 100 | "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, | |
101 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 101 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
102 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 102 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
103 | 103 | |||
104 | { /* (6) AMD defined 80000001 ecx */ | 104 | { /* (6) AMD defined 80000001 ecx */ | |
105 | "lahf_lm", "cmp_legacy", "svm", "extapic", | 105 | "lahf_lm", "cmp_legacy", "svm", "extapic", | |
106 | "cr8_legacy", "abm", "sse4a", "misalignsse", | 106 | "cr8_legacy", "abm", "sse4a", "misalignsse", | |
107 | "3dnowprefetch", "osvw", "ibs", "xop", "skinit", "wdt", NULL, "lwp", | 107 | "3dnowprefetch", "osvw", "ibs", "xop", "skinit", "wdt", NULL, "lwp", | |
108 | "fma4", "tce", NULL, "nodeid_msr", | 108 | "fma4", "tce", NULL, "nodeid_msr", | |
109 | NULL, "tbm", "topoext", "perfctr_core", | 109 | NULL, "tbm", "topoext", "perfctr_core", | |
110 | "perfctr_nb", NULL, "bpext", "ptsc", | 110 | "perfctr_nb", NULL, "bpext", "ptsc", | |
111 | "perfctr_llc", "mwaitx", NULL, NULL}, | 111 | "perfctr_llc", "mwaitx", NULL, NULL}, | |
112 | 112 | |||
113 | { /* (7) Linux mapping */ | 113 | { /* (7) Linux mapping */ | |
114 | NULL, NULL, "cpb", "ebp", NULL, "pln", "pts", "dtherm", | 114 | NULL, NULL, "cpb", "ebp", NULL, "pln", "pts", "dtherm", | |
115 | "hw_pstate", "proc_feedback", "sme", NULL, | 115 | "hw_pstate", "proc_feedback", "sme", NULL, | |
116 | NULL, NULL, NULL, NULL, | 116 | NULL, NULL, NULL, NULL, | |
117 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 117 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
118 | NULL, "ibrs", "ibpb", "stibp", NULL, NULL, NULL, NULL}, | 118 | NULL, "ibrs", "ibpb", "stibp", NULL, NULL, NULL, NULL}, | |
119 | 119 | |||
120 | { /* (8) Linux mapping */ | 120 | { /* (8) Linux mapping */ | |
121 | "tpr_shadow", "vnmi", "flexpriority", "ept", | 121 | "tpr_shadow", "vnmi", "flexpriority", "ept", | |
122 | "vpid", "npt", "lbrv", "svm_lock", | 122 | "vpid", "npt", "lbrv", "svm_lock", | |
123 | "nrip_save", "tsc_scale", "vmcb_clean", "flushbyasid", | 123 | "nrip_save", "tsc_scale", "vmcb_clean", "flushbyasid", | |
124 | "decodeassists", "pausefilter", "pfthreshold", "vmmcall", | 124 | "decodeassists", "pausefilter", "pfthreshold", "vmmcall", | |
125 | NULL, "ept_ad", NULL, NULL, NULL, NULL, NULL, NULL, | 125 | NULL, "ept_ad", NULL, NULL, NULL, NULL, NULL, NULL, | |
126 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 126 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
127 | 127 | |||
128 | { /* (9) Intel-defined: 00000007 ebx */ | 128 | { /* (9) Intel-defined: 00000007 ebx */ | |
129 | "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep", | 129 | "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep", | |
130 | "bmi2", "erms", "invpcid", "rtm", "cqm", NULL, "mpx", "rdt_a", | 130 | "bmi2", "erms", "invpcid", "rtm", "cqm", NULL, "mpx", "rdt_a", | |
131 | "avx512f", "avx512dq", "rdseed", "adx", | 131 | "avx512f", "avx512dq", "rdseed", "adx", | |
132 | "smap", "avx512ifma", NULL, "clflushopt", | 132 | "smap", "avx512ifma", NULL, "clflushopt", | |
133 | "clwb", "intel_pt", "avx512pf", "avx512er", | 133 | "clwb", "intel_pt", "avx512pf", "avx512er", | |
134 | "avx512cd", "sha_ni", "avx512bw", "avx512vl"}, | 134 | "avx512cd", "sha_ni", "avx512bw", "avx512vl"}, | |
135 | 135 | |||
136 | { /* (10) 0x0000000d:1 eax */ | 136 | { /* (10) 0x0000000d:1 eax */ | |
137 | "xsaveopt", "xsavec", "xgetbv1", "xsaves", NULL, NULL, NULL, NULL, | 137 | "xsaveopt", "xsavec", "xgetbv1", "xsaves", NULL, NULL, NULL, NULL, | |
138 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 138 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
139 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 139 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
140 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 140 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
141 | 141 | |||
142 | { /* (11) 0x0000000f:0 edx */ | 142 | { /* (11) 0x0000000f:0 edx */ | |
143 | NULL, "cqm_llc", NULL, NULL, NULL, NULL, NULL, NULL, | 143 | NULL, "cqm_llc", NULL, NULL, NULL, NULL, NULL, NULL, | |
144 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 144 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
145 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 145 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
146 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 146 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
147 | 147 | |||
148 | { /* (12) 0x0000000f:1 edx */ | 148 | { /* (12) 0x0000000f:1 edx */ | |
149 | "cqm_occup_llc", "cqm_mbm_total", "cqm_mbm_local", NULL, | 149 | "cqm_occup_llc", "cqm_mbm_total", "cqm_mbm_local", NULL, | |
150 | NULL, NULL, NULL, NULL, | 150 | NULL, NULL, NULL, NULL, | |
151 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 151 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
152 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 152 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
153 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 153 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
154 | 154 | |||
155 | { /* (13) AMD 0x80000008 ebx */ | 155 | { /* (13) AMD 0x80000008 ebx */ | |
156 | "clzero", "irperf", "xsaveerptr", NULL, "rdpru", NULL, NULL, NULL, | 156 | "clzero", "irperf", "xsaveerptr", NULL, "rdpru", NULL, NULL, NULL, | |
157 | NULL, "wbnoinvd", NULL, NULL, NULL, NULL, NULL, NULL, | 157 | NULL, "wbnoinvd", NULL, NULL, NULL, NULL, NULL, NULL, | |
158 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 158 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
159 | NULL, "virt_ssbd", NULL, NULL, NULL, NULL, NULL, NULL}, | 159 | NULL, "virt_ssbd", NULL, NULL, NULL, NULL, NULL, NULL}, | |
160 | 160 | |||
161 | { /* (14) 0x00000006 eax */ | 161 | { /* (14) 0x00000006 eax */ | |
162 | "dtherm", "ida", "arat", NULL, "pln", NULL, "pts", "hwp", | 162 | "dtherm", "ida", "arat", NULL, "pln", NULL, "pts", "hwp", | |
163 | "hwp_notify", "hwp_act_window", "hwp_epp","hwp_pkg_req", | 163 | "hwp_notify", "hwp_act_window", "hwp_epp","hwp_pkg_req", | |
164 | NULL, NULL, NULL, NULL, | 164 | NULL, NULL, NULL, NULL, | |
165 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 165 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
166 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 166 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
167 | 167 | |||
168 | { /* (15) 0x8000000a edx */ | 168 | { /* (15) 0x8000000a edx */ | |
169 | "npt", "lbrv", "svm_lock", "nrip_save", | 169 | "npt", "lbrv", "svm_lock", "nrip_save", | |
170 | "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists", | 170 | "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists", | |
171 | NULL, NULL, "pausefilter", NULL, "pfthreshold", "avic", NULL, | 171 | NULL, NULL, "pausefilter", NULL, "pfthreshold", "avic", NULL, | |
172 | "v_vmsave_vmload", | 172 | "v_vmsave_vmload", | |
173 | "vgif", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 173 | "vgif", NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
174 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 174 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
175 | 175 | |||
176 | { /* (16) 0x00000007:0 ecx */ | 176 | { /* (16) 0x00000007:0 ecx */ | |
177 | NULL, "avx512vbmi", "umip", "pku", | 177 | NULL, "avx512vbmi", "umip", "pku", | |
178 | "ospke", "waitpkg", "avx512_vbmi2", NULL, | 178 | "ospke", "waitpkg", "avx512_vbmi2", NULL, | |
179 | "gfni", "vaes", "vpclmulqdq", "avx512_vnni", | 179 | "gfni", "vaes", "vpclmulqdq", "avx512_vnni", | |
180 | "avx512_bitalg", "tme", "avx512_vpopcntdq", NULL, | 180 | "avx512_bitalg", "tme", "avx512_vpopcntdq", NULL, | |
181 | "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, | 181 | "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, | |
182 | NULL, "cldemote", NULL, "movdiri", "movdir64b", NULL, NULL, NULL}, | 182 | NULL, "cldemote", NULL, "movdiri", "movdir64b", NULL, NULL, NULL}, | |
183 | 183 | |||
184 | { /* (17) 0x80000007 ebx */ | 184 | { /* (17) 0x80000007 ebx */ | |
185 | "overflow_recov", "succor", NULL, "smca", NULL, NULL, NULL, NULL, | 185 | "overflow_recov", "succor", NULL, "smca", NULL, NULL, NULL, NULL, | |
186 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 186 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
187 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 187 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
188 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 188 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | |
189 | 189 | |||
190 | { /* (18) Intel 0x00000007 edx */ | 190 | { /* (18) Intel 0x00000007 edx */ | |
191 | NULL, NULL, "avx512_4vnniw", "avx512_4fmaps", NULL, NULL, NULL, NULL, | 191 | NULL, NULL, "avx512_4vnniw", "avx512_4fmaps", "fsrm", NULL, NULL, NULL, | |
192 | NULL, NULL, "md_clear", NULL, NULL, NULL, NULL, NULL, | 192 | "vp2intersect", NULL, "md_clear", NULL, NULL, NULL, NULL, NULL, | |
193 | NULL, NULL, "pconfig", NULL, NULL, NULL, NULL, NULL, | 193 | NULL, NULL, "pconfig", NULL, NULL, NULL, NULL, NULL, | |
194 | NULL, NULL, NULL, NULL, | 194 | NULL, NULL, NULL, NULL, | |
195 | "flush_l1d", "arch_capabilities", NULL, "ssbd"}, | 195 | "flush_l1d", "arch_capabilities", NULL, "ssbd"}, | |
196 | }; | 196 | }; | |
197 | 197 | |||
198 | static int procfs_getonecpu(int, struct cpu_info *, char *, size_t *); | 198 | static int procfs_getonecpu(int, struct cpu_info *, char *, size_t *); | |
199 | 199 | |||
200 | /* | 200 | /* | |
201 | * Linux-style /proc/cpuinfo. | 201 | * Linux-style /proc/cpuinfo. | |
202 | * Only used when procfs is mounted with -o linux. | 202 | * Only used when procfs is mounted with -o linux. | |
203 | * | 203 | * | |
204 | * In the multiprocessor case, this should be a loop over all CPUs. | 204 | * In the multiprocessor case, this should be a loop over all CPUs. | |
205 | */ | 205 | */ | |
206 | int | 206 | int | |
207 | procfs_getcpuinfstr(char *bf, size_t *len) | 207 | procfs_getcpuinfstr(char *bf, size_t *len) | |
208 | { | 208 | { | |
209 | struct cpu_info *ci; | 209 | struct cpu_info *ci; | |
210 | CPU_INFO_ITERATOR cii; | 210 | CPU_INFO_ITERATOR cii; | |
211 | size_t i, total, size, used; | 211 | size_t i, total, size, used; | |
212 | 212 | |||
213 | i = total = 0; | 213 | i = total = 0; | |
214 | used = size = *len; | 214 | used = size = *len; | |
215 | 215 | |||
216 | for (CPU_INFO_FOREACH(cii, ci)) { | 216 | for (CPU_INFO_FOREACH(cii, ci)) { | |
217 | procfs_getonecpu(i++, ci, bf, &used); | 217 | procfs_getonecpu(i++, ci, bf, &used); | |
218 | total += used + 1; | 218 | total += used + 1; | |
219 | if (used + 1 <= size) { | 219 | if (used + 1 <= size) { | |
220 | bf += used; | 220 | bf += used; | |
221 | *bf++ = '\n'; | 221 | *bf++ = '\n'; | |
222 | size -= used + 1; | 222 | size -= used + 1; | |
223 | used = size; | 223 | used = size; | |
224 | } else | 224 | } else | |
225 | used = 0; | 225 | used = 0; | |
226 | } | 226 | } | |
227 | size = *len; | 227 | size = *len; | |
228 | *len = total; | 228 | *len = total; | |
229 | return size < *len ? -1 : 0; | 229 | return size < *len ? -1 : 0; | |
230 | } | 230 | } | |
231 | 231 | |||
232 | static int | 232 | static int | |
233 | procfs_getonefeatreg(uint32_t reg, const char * const *table, char *p, | 233 | procfs_getonefeatreg(uint32_t reg, const char * const *table, char *p, | |
234 | size_t *left) | 234 | size_t *left) | |
235 | { | 235 | { | |
236 | size_t l; | 236 | size_t l; | |
237 | 237 | |||
238 | for (size_t i = 0; i < 32; i++) { | 238 | for (size_t i = 0; i < 32; i++) { | |
239 | if ((reg & (1U << i)) && table[i]) { | 239 | if ((reg & (1U << i)) && table[i]) { | |
240 | l = snprintf(p, *left, "%s ", table[i]); | 240 | l = snprintf(p, *left, "%s ", table[i]); | |
241 | if (l < *left) { | 241 | if (l < *left) { | |
242 | *left -= l; | 242 | *left -= l; | |
243 | p += l; | 243 | p += l; | |
244 | } else | 244 | } else | |
245 | break; | 245 | break; | |
246 | } | 246 | } | |
247 | } | 247 | } | |
248 | 248 | |||
249 | return 0; /* XXX */ | 249 | return 0; /* XXX */ | |
250 | } | 250 | } | |
251 | 251 | |||
252 | /* | 252 | /* | |
253 | * Print feature bits. The code assume that unused entry of x86_features[] | 253 | * Print feature bits. The code assume that unused entry of x86_features[] | |
254 | * is zero-cleared. | 254 | * is zero-cleared. | |
255 | * | 255 | * | |
256 | * XXX This function will be rewritten when all of linux entries are | 256 | * XXX This function will be rewritten when all of linux entries are | |
257 | * decoded. | 257 | * decoded. | |
258 | */ | 258 | */ | |
259 | static int | 259 | static int | |
260 | procfs_getonecpufeatures(struct cpu_info *ci, char *p, size_t *left) | 260 | procfs_getonecpufeatures(struct cpu_info *ci, char *p, size_t *left) | |
261 | { | 261 | { | |
262 | size_t last = *left; | 262 | size_t last = *left; | |
263 | size_t diff; | 263 | size_t diff; | |
264 | u_int descs[4]; | 264 | u_int descs[4]; | |
265 | 265 | |||
266 | procfs_getonefeatreg(ci->ci_feat_val[0], x86_features[0], p, left); | 266 | procfs_getonefeatreg(ci->ci_feat_val[0], x86_features[0], p, left); | |
267 | diff = last - *left; | 267 | diff = last - *left; | |
268 | 268 | |||
269 | procfs_getonefeatreg(ci->ci_feat_val[2], x86_features[1], p + diff, | 269 | procfs_getonefeatreg(ci->ci_feat_val[2], x86_features[1], p + diff, | |
270 | left); | 270 | left); | |
271 | diff = last - *left; | 271 | diff = last - *left; | |
272 | 272 | |||
273 | /* x86_features[2] is for Transmeta */ | 273 | /* x86_features[2] is for Transmeta */ | |
274 | /* x86_features[3] is Linux defined mapping */ | 274 | /* x86_features[3] is Linux defined mapping */ | |
275 | 275 | |||
276 | procfs_getonefeatreg(ci->ci_feat_val[1], x86_features[4], p + diff, | 276 | procfs_getonefeatreg(ci->ci_feat_val[1], x86_features[4], p + diff, | |
277 | left); | 277 | left); | |
278 | diff = last - *left; | 278 | diff = last - *left; | |
279 | 279 | |||
280 | procfs_getonefeatreg(ci->ci_feat_val[4], x86_features[5], p + diff, | 280 | procfs_getonefeatreg(ci->ci_feat_val[4], x86_features[5], p + diff, | |
281 | left); | 281 | left); | |
282 | diff = last - *left; | 282 | diff = last - *left; | |
283 | 283 | |||
284 | procfs_getonefeatreg(ci->ci_feat_val[3], x86_features[6], p + diff, | 284 | procfs_getonefeatreg(ci->ci_feat_val[3], x86_features[6], p + diff, | |
285 | left); | 285 | left); | |
286 | diff = last - *left; | 286 | diff = last - *left; | |
287 | 287 | |||
288 | /* x86_features[7] is Linux defined mapping */ | 288 | /* x86_features[7] is Linux defined mapping */ | |
289 | /* x86_features[8] is Linux defined mapping */ | 289 | /* x86_features[8] is Linux defined mapping */ | |
290 | 290 | |||
291 | procfs_getonefeatreg(ci->ci_feat_val[5], x86_features[9], p + diff, | 291 | procfs_getonefeatreg(ci->ci_feat_val[5], x86_features[9], p + diff, | |
292 | left); | 292 | left); | |
293 | diff = last - *left; | 293 | diff = last - *left; | |
294 | 294 | |||
295 | if (ci->ci_max_cpuid >= 0x0d) { | 295 | if (ci->ci_max_cpuid >= 0x0d) { | |
296 | x86_cpuid2(0x0d, 1, descs); | 296 | x86_cpuid2(0x0d, 1, descs); | |
297 | procfs_getonefeatreg(descs[0], x86_features[10], p + diff, | 297 | procfs_getonefeatreg(descs[0], x86_features[10], p + diff, | |
298 | left); | 298 | left); | |
299 | diff = last - *left; | 299 | diff = last - *left; | |
300 | } | 300 | } | |
301 | 301 | |||
302 | if (ci->ci_max_cpuid >= 0x0f) { | 302 | if (ci->ci_max_cpuid >= 0x0f) { | |
303 | x86_cpuid2(0x0f, 0, descs); | 303 | x86_cpuid2(0x0f, 0, descs); | |
304 | procfs_getonefeatreg(descs[3], x86_features[11], p + diff, | 304 | procfs_getonefeatreg(descs[3], x86_features[11], p + diff, | |
305 | left); | 305 | left); | |
306 | diff = last - *left; | 306 | diff = last - *left; | |
307 | 307 | |||
308 | x86_cpuid2(0x0f, 1, descs); | 308 | x86_cpuid2(0x0f, 1, descs); | |
309 | procfs_getonefeatreg(descs[3], x86_features[12], p + diff, | 309 | procfs_getonefeatreg(descs[3], x86_features[12], p + diff, | |
310 | left); | 310 | left); | |
311 | diff = last - *left; | 311 | diff = last - *left; | |
312 | } | 312 | } | |
313 | 313 | |||
314 | if ((cpu_vendor == CPUVENDOR_AMD) | 314 | if ((cpu_vendor == CPUVENDOR_AMD) | |
315 | && (ci->ci_max_ext_cpuid >= 0x80000008)) { | 315 | && (ci->ci_max_ext_cpuid >= 0x80000008)) { | |
316 | x86_cpuid(0x80000008, descs); | 316 | x86_cpuid(0x80000008, descs); | |
317 | procfs_getonefeatreg(descs[1], x86_features[13], p + diff, | 317 | procfs_getonefeatreg(descs[1], x86_features[13], p + diff, | |
318 | left); | 318 | left); | |
319 | diff = last - *left; | 319 | diff = last - *left; | |
320 | } | 320 | } | |
321 | 321 | |||
322 | if (ci->ci_max_cpuid >= 0x06) { | 322 | if (ci->ci_max_cpuid >= 0x06) { | |
323 | x86_cpuid(0x06, descs); | 323 | x86_cpuid(0x06, descs); | |
324 | procfs_getonefeatreg(descs[0], x86_features[14], p + diff, | 324 | procfs_getonefeatreg(descs[0], x86_features[14], p + diff, | |
325 | left); | 325 | left); | |
326 | diff = last - *left; | 326 | diff = last - *left; | |
327 | } | 327 | } | |
328 | 328 | |||
329 | if ((cpu_vendor == CPUVENDOR_AMD) | 329 | if ((cpu_vendor == CPUVENDOR_AMD) | |
330 | && (ci->ci_max_ext_cpuid >= 0x8000000a)) { | 330 | && (ci->ci_max_ext_cpuid >= 0x8000000a)) { | |
331 | x86_cpuid(0x8000000a, descs); | 331 | x86_cpuid(0x8000000a, descs); | |
332 | procfs_getonefeatreg(descs[3], x86_features[15], p + diff, | 332 | procfs_getonefeatreg(descs[3], x86_features[15], p + diff, | |
333 | left); | 333 | left); | |
334 | diff = last - *left; | 334 | diff = last - *left; | |
335 | } | 335 | } | |
336 | 336 | |||
337 | procfs_getonefeatreg(ci->ci_feat_val[6], x86_features[16], p + diff, | 337 | procfs_getonefeatreg(ci->ci_feat_val[6], x86_features[16], p + diff, | |
338 | left); | 338 | left); | |
339 | diff = last - *left; | 339 | diff = last - *left; | |
340 | 340 | |||
341 | if ((cpu_vendor == CPUVENDOR_AMD) | 341 | if ((cpu_vendor == CPUVENDOR_AMD) | |
342 | && (ci->ci_max_ext_cpuid >= 0x80000007)) { | 342 | && (ci->ci_max_ext_cpuid >= 0x80000007)) { | |
343 | x86_cpuid(0x80000007, descs); | 343 | x86_cpuid(0x80000007, descs); | |
344 | procfs_getonefeatreg(descs[1], x86_features[17], p + diff, | 344 | procfs_getonefeatreg(descs[1], x86_features[17], p + diff, | |
345 | left); | 345 | left); | |
346 | diff = last - *left; | 346 | diff = last - *left; | |
347 | } | 347 | } | |
348 | 348 | |||
349 | if ((cpu_vendor == CPUVENDOR_INTEL) | 349 | if ((cpu_vendor == CPUVENDOR_INTEL) | |
350 | && (ci->ci_max_cpuid >= 0x00000007)) { | 350 | && (ci->ci_max_cpuid >= 0x00000007)) { | |
351 | x86_cpuid(0x00000007, descs); | 351 | x86_cpuid(0x00000007, descs); | |
352 | procfs_getonefeatreg(descs[3], x86_features[18], p + diff, | 352 | procfs_getonefeatreg(descs[3], x86_features[18], p + diff, | |
353 | left); | 353 | left); | |
354 | diff = last - *left; | 354 | diff = last - *left; | |
355 | } | 355 | } | |
356 | 356 | |||
357 | return 0; /* XXX */ | 357 | return 0; /* XXX */ | |
358 | } | 358 | } | |
359 | 359 | |||
360 | static int | 360 | static int | |
361 | procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, size_t *len) | 361 | procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, size_t *len) | |
362 | { | 362 | { | |
363 | size_t left, l, size; | 363 | size_t left, l, size; | |
364 | char featurebuf[1024], *p; | 364 | char featurebuf[1024], *p; | |
365 | 365 | |||
366 | p = featurebuf; | 366 | p = featurebuf; | |
367 | left = sizeof(featurebuf); | 367 | left = sizeof(featurebuf); | |
368 | size = *len; | 368 | size = *len; | |
369 | procfs_getonecpufeatures(ci, p, &left); | 369 | procfs_getonecpufeatures(ci, p, &left); | |
370 | 370 | |||
371 | p = bf; | 371 | p = bf; | |
372 | left = *len; | 372 | left = *len; | |
373 | size = 0; | 373 | size = 0; | |
374 | l = snprintf(p, left, | 374 | l = snprintf(p, left, | |
375 | "processor\t: %d\n" | 375 | "processor\t: %d\n" | |
376 | "vendor_id\t: %s\n" | 376 | "vendor_id\t: %s\n" | |
377 | "cpu family\t: %d\n" | 377 | "cpu family\t: %d\n" | |
378 | "model\t\t: %d\n" | 378 | "model\t\t: %d\n" | |
379 | "model name\t: %s\n" | 379 | "model name\t: %s\n" | |
380 | "stepping\t: ", | 380 | "stepping\t: ", | |
381 | xcpu, | 381 | xcpu, | |
382 | (char *)ci->ci_vendor, | 382 | (char *)ci->ci_vendor, | |
383 | CPUID_TO_FAMILY(ci->ci_signature), | 383 | CPUID_TO_FAMILY(ci->ci_signature), | |
384 | CPUID_TO_MODEL(ci->ci_signature), | 384 | CPUID_TO_MODEL(ci->ci_signature), | |
385 | cpu_brand_string | 385 | cpu_brand_string | |
386 | ); | 386 | ); | |
387 | size += l; | 387 | size += l; | |
388 | if (l < left) { | 388 | if (l < left) { | |
389 | left -= l; | 389 | left -= l; | |
390 | p += l; | 390 | p += l; | |
391 | } else | 391 | } else | |
392 | left = 0; | 392 | left = 0; | |
393 | 393 | |||
394 | if (cpuid_level >= 0) | 394 | if (cpuid_level >= 0) | |
395 | l = snprintf(p, left, "%d\n", | 395 | l = snprintf(p, left, "%d\n", | |
396 | CPUID_TO_STEPPING(ci->ci_signature)); | 396 | CPUID_TO_STEPPING(ci->ci_signature)); | |
397 | else | 397 | else | |
398 | l = snprintf(p, left, "unknown\n"); | 398 | l = snprintf(p, left, "unknown\n"); | |
399 | 399 | |||
400 | size += l; | 400 | size += l; | |
401 | if (l < left) { | 401 | if (l < left) { | |
402 | left -= l; | 402 | left -= l; | |
403 | p += l; | 403 | p += l; | |
404 | } else | 404 | } else | |
405 | left = 0; | 405 | left = 0; | |
406 | 406 | |||
407 | if (ci->ci_data.cpu_cc_freq != 0) { | 407 | if (ci->ci_data.cpu_cc_freq != 0) { | |
408 | uint64_t freq, fraq; | 408 | uint64_t freq, fraq; | |
409 | 409 | |||
410 | freq = (ci->ci_data.cpu_cc_freq + 4999) / 1000000; | 410 | freq = (ci->ci_data.cpu_cc_freq + 4999) / 1000000; | |
411 | fraq = ((ci->ci_data.cpu_cc_freq + 4999) / 10000) % 100; | 411 | fraq = ((ci->ci_data.cpu_cc_freq + 4999) / 10000) % 100; | |
412 | l = snprintf(p, left, "cpu MHz\t\t: %" PRIu64 ".%02" PRIu64 | 412 | l = snprintf(p, left, "cpu MHz\t\t: %" PRIu64 ".%02" PRIu64 | |
413 | "\n", freq, fraq); | 413 | "\n", freq, fraq); | |
414 | } else | 414 | } else | |
415 | l = snprintf(p, left, "cpu MHz\t\t: unknown\n"); | 415 | l = snprintf(p, left, "cpu MHz\t\t: unknown\n"); | |
416 | 416 | |||
417 | size += l; | 417 | size += l; | |
418 | if (l < left) { | 418 | if (l < left) { | |
419 | left -= l; | 419 | left -= l; | |
420 | p += l; | 420 | p += l; | |
421 | } else | 421 | } else | |
422 | left = 0; | 422 | left = 0; | |
423 | 423 | |||
424 | l = snprintf(p, left, | 424 | l = snprintf(p, left, | |
425 | "apicid\t\t: %lu\n" | 425 | "apicid\t\t: %lu\n" | |
426 | "initial apicid\t: %u\n", | 426 | "initial apicid\t: %u\n", | |
427 | ci->ci_cpuid, | 427 | ci->ci_cpuid, | |
428 | ci->ci_initapicid | 428 | ci->ci_initapicid | |
429 | ); | 429 | ); | |
430 | size += l; | 430 | size += l; | |
431 | if (l < left) { | 431 | if (l < left) { | |
432 | left -= l; | 432 | left -= l; | |
433 | p += l; | 433 | p += l; | |
434 | } else | 434 | } else | |
435 | left = 0; | 435 | left = 0; | |
436 | 436 | |||
437 | l = snprintf(p, left, | 437 | l = snprintf(p, left, | |
438 | #ifdef __i386__ | 438 | #ifdef __i386__ | |
439 | "fdiv_bug\t: %s\n" | 439 | "fdiv_bug\t: %s\n" | |
440 | #endif | 440 | #endif | |
441 | "fpu\t\t: yes\n" | 441 | "fpu\t\t: yes\n" | |
442 | "fpu_exception\t: yes\n" | 442 | "fpu_exception\t: yes\n" | |
443 | "cpuid level\t: %d\n" | 443 | "cpuid level\t: %d\n" | |
444 | "wp\t\t: %s\n" | 444 | "wp\t\t: %s\n" | |
445 | "flags\t\t: %s\n" | 445 | "flags\t\t: %s\n" | |
446 | "clflush size\t: %d\n", | 446 | "clflush size\t: %d\n", | |
447 | #ifdef __i386__ | 447 | #ifdef __i386__ | |
448 | i386_fpu_fdivbug ? "yes" : "no", /* an old pentium */ | 448 | i386_fpu_fdivbug ? "yes" : "no", /* an old pentium */ | |
449 | #endif | 449 | #endif | |
450 | ci->ci_max_cpuid, | 450 | ci->ci_max_cpuid, | |
451 | (rcr0() & CR0_WP) ? "yes" : "no", | 451 | (rcr0() & CR0_WP) ? "yes" : "no", | |
452 | featurebuf, | 452 | featurebuf, | |
453 | ci->ci_cflush_lsize | 453 | ci->ci_cflush_lsize | |
454 | ); | 454 | ); | |
455 | size += l; | 455 | size += l; | |
456 | 456 | |||
457 | left = *len; | 457 | left = *len; | |
458 | *len = size; | 458 | *len = size; | |
459 | return left < *len ? -1 : 0; | 459 | return left < *len ? -1 : 0; | |
460 | } | 460 | } | |
461 | 461 | |||
462 | #if defined(__HAVE_PROCFS_MACHDEP) && !defined(__x86_64__) | 462 | #if defined(__HAVE_PROCFS_MACHDEP) && !defined(__x86_64__) | |
463 | 463 | |||
464 | void | 464 | void | |
465 | procfs_machdep_allocvp(struct vnode *vp) | 465 | procfs_machdep_allocvp(struct vnode *vp) | |
466 | { | 466 | { | |
467 | struct pfsnode *pfs = vp->v_data; | 467 | struct pfsnode *pfs = vp->v_data; | |
468 | 468 | |||
469 | switch (pfs->pfs_type) { | 469 | switch (pfs->pfs_type) { | |
470 | case Pmachdep_xmmregs: | 470 | case Pmachdep_xmmregs: | |
471 | /* /proc/N/xmmregs = -rw------- */ | 471 | /* /proc/N/xmmregs = -rw------- */ | |
472 | pfs->pfs_mode = S_IRUSR|S_IWUSR; | 472 | pfs->pfs_mode = S_IRUSR|S_IWUSR; | |
473 | vp->v_type = VREG; | 473 | vp->v_type = VREG; | |
474 | break; | 474 | break; | |
475 | default: | 475 | default: | |
476 | KASSERT(false); | 476 | KASSERT(false); | |
477 | } | 477 | } | |
478 | } | 478 | } | |
479 | 479 | |||
480 | int | 480 | int | |
481 | procfs_machdep_rw(struct lwp *curl, struct lwp *l, struct pfsnode *pfs, | 481 | procfs_machdep_rw(struct lwp *curl, struct lwp *l, struct pfsnode *pfs, | |
482 | struct uio *uio) | 482 | struct uio *uio) | |
483 | { | 483 | { | |
484 | 484 | |||
485 | switch (pfs->pfs_type) { | 485 | switch (pfs->pfs_type) { | |
486 | case Pmachdep_xmmregs: | 486 | case Pmachdep_xmmregs: | |
487 | return (procfs_machdep_doxmmregs(curl, l, pfs, uio)); | 487 | return (procfs_machdep_doxmmregs(curl, l, pfs, uio)); | |
488 | default: | 488 | default: | |
489 | KASSERT(false); | 489 | KASSERT(false); | |
490 | } | 490 | } | |
491 | return EINVAL; | 491 | return EINVAL; | |
492 | } | 492 | } | |
493 | 493 | |||
494 | int | 494 | int | |
495 | procfs_machdep_getattr(struct vnode *vp, struct vattr *vap, struct proc *procp) | 495 | procfs_machdep_getattr(struct vnode *vp, struct vattr *vap, struct proc *procp) | |
496 | { | 496 | { | |
497 | struct pfsnode *pfs = VTOPFS(vp); | 497 | struct pfsnode *pfs = VTOPFS(vp); | |
498 | 498 | |||
499 | switch (pfs->pfs_type) { | 499 | switch (pfs->pfs_type) { | |
500 | case Pmachdep_xmmregs: | 500 | case Pmachdep_xmmregs: | |
501 | vap->va_bytes = vap->va_size = sizeof(struct xmmregs); | 501 | vap->va_bytes = vap->va_size = sizeof(struct xmmregs); | |
502 | break; | 502 | break; | |
503 | default: | 503 | default: | |
504 | KASSERT(false); | 504 | KASSERT(false); | |
505 | } | 505 | } | |
506 | return 0; | 506 | return 0; | |
507 | } | 507 | } | |
508 | 508 | |||
509 | int | 509 | int | |
510 | procfs_machdep_doxmmregs(struct lwp *curl, struct lwp *l, | 510 | procfs_machdep_doxmmregs(struct lwp *curl, struct lwp *l, | |
511 | struct pfsnode *pfs, struct uio *uio) | 511 | struct pfsnode *pfs, struct uio *uio) | |
512 | { | 512 | { | |
513 | 513 | |||
514 | return process_machdep_doxmmregs(curl, l, uio); | 514 | return process_machdep_doxmmregs(curl, l, uio); | |
515 | } | 515 | } | |
516 | 516 | |||
517 | int | 517 | int | |
518 | procfs_machdep_validxmmregs(struct lwp *l, struct mount *mp) | 518 | procfs_machdep_validxmmregs(struct lwp *l, struct mount *mp) | |
519 | { | 519 | { | |
520 | 520 | |||
521 | return process_machdep_validxmmregs(l->l_proc); | 521 | return process_machdep_validxmmregs(l->l_proc); | |
522 | } | 522 | } | |
523 | 523 | |||
524 | #endif | 524 | #endif |
--- src/sys/arch/x86/x86/tsc.c 2017/10/02 19:23:16 1.37
+++ src/sys/arch/x86/x86/tsc.c 2020/04/14 17:15:02 1.37.8.1
@@ -1,321 +1,321 @@ | @@ -1,321 +1,321 @@ | |||
1 | /* $NetBSD: tsc.c,v 1.37 2017/10/02 19:23:16 maxv Exp $ */ | 1 | /* $NetBSD: tsc.c,v 1.37.8.1 2020/04/14 17:15:02 martin Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
15 | * | 15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.37 2017/10/02 19:23:16 maxv Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.37.8.1 2020/04/14 17:15:02 martin Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/time.h> | 34 | #include <sys/time.h> | |
35 | #include <sys/timetc.h> | 35 | #include <sys/timetc.h> | |
36 | #include <sys/lwp.h> | 36 | #include <sys/lwp.h> | |
37 | #include <sys/atomic.h> | 37 | #include <sys/atomic.h> | |
38 | #include <sys/kernel.h> | 38 | #include <sys/kernel.h> | |
39 | #include <sys/cpu.h> | 39 | #include <sys/cpu.h> | |
40 | #include <sys/xcall.h> | 40 | #include <sys/xcall.h> | |
41 | 41 | |||
42 | #include <machine/cpu_counter.h> | 42 | #include <machine/cpu_counter.h> | |
43 | #include <machine/cpuvar.h> | 43 | #include <machine/cpuvar.h> | |
44 | #include <machine/cpufunc.h> | 44 | #include <machine/cpufunc.h> | |
45 | #include <machine/specialreg.h> | 45 | #include <machine/specialreg.h> | |
46 | #include <machine/cputypes.h> | 46 | #include <machine/cputypes.h> | |
47 | 47 | |||
48 | #include "tsc.h" | 48 | #include "tsc.h" | |
49 | 49 | |||
50 | u_int tsc_get_timecount(struct timecounter *); | 50 | u_int tsc_get_timecount(struct timecounter *); | |
51 | 51 | |||
52 | uint64_t tsc_freq; /* exported for sysctl */ | 52 | uint64_t tsc_freq; /* exported for sysctl */ | |
53 | static int64_t tsc_drift_max = 250; /* max cycles */ | 53 | static int64_t tsc_drift_max = 250; /* max cycles */ | |
54 | static int64_t tsc_drift_observed; | 54 | static int64_t tsc_drift_observed; | |
55 | static bool tsc_good; | 55 | static bool tsc_good; | |
56 | 56 | |||
57 | int tsc_user_enabled = 1; | 57 | int tsc_user_enabled = 1; | |
58 | 58 | |||
59 | static volatile int64_t tsc_sync_val; | 59 | static volatile int64_t tsc_sync_val; | |
60 | static volatile struct cpu_info *tsc_sync_cpu; | 60 | static volatile struct cpu_info *tsc_sync_cpu; | |
61 | 61 | |||
62 | static struct timecounter tsc_timecounter = { | 62 | static struct timecounter tsc_timecounter = { | |
63 | .tc_get_timecount = tsc_get_timecount, | 63 | .tc_get_timecount = tsc_get_timecount, | |
64 | .tc_counter_mask = ~0U, | 64 | .tc_counter_mask = ~0U, | |
65 | .tc_name = "TSC", | 65 | .tc_name = "TSC", | |
66 | .tc_quality = 3000, | 66 | .tc_quality = 3000, | |
67 | }; | 67 | }; | |
68 | 68 | |||
69 | bool | 69 | bool | |
70 | tsc_is_invariant(void) | 70 | tsc_is_invariant(void) | |
71 | { | 71 | { | |
72 | struct cpu_info *ci; | 72 | struct cpu_info *ci; | |
73 | uint32_t descs[4]; | 73 | uint32_t descs[4]; | |
74 | uint32_t family; | 74 | uint32_t family; | |
75 | bool invariant; | 75 | bool invariant; | |
76 | 76 | |||
77 | if (!cpu_hascounter()) | 77 | if (!cpu_hascounter()) | |
78 | return false; | 78 | return false; | |
79 | 79 | |||
80 | ci = curcpu(); | 80 | ci = curcpu(); | |
81 | invariant = false; | 81 | invariant = false; | |
82 | 82 | |||
83 | if (cpu_vendor == CPUVENDOR_INTEL) { | 83 | if (cpu_vendor == CPUVENDOR_INTEL) { | |
84 | /* | 84 | /* | |
85 | * From Intel(tm) 64 and IA-32 Architectures Software | 85 | * From Intel(tm) 64 and IA-32 Architectures Software | |
86 | * Developer's Manual Volume 3A: System Programming Guide, | 86 | * Developer's Manual Volume 3A: System Programming Guide, | |
87 | * Part 1, 17.13 TIME_STAMP COUNTER, these are the processors | 87 | * Part 1, 17.13 TIME_STAMP COUNTER, these are the processors | |
88 | * where the TSC is known invariant: | 88 | * where the TSC is known invariant: | |
89 | * | 89 | * | |
90 | * Pentium 4, Intel Xeon (family 0f, models 03 and higher) | 90 | * Pentium 4, Intel Xeon (family 0f, models 03 and higher) | |
91 | * Core Solo and Core Duo processors (family 06, model 0e) | 91 | * Core Solo and Core Duo processors (family 06, model 0e) | |
92 | * Xeon 5100 series and Core 2 Duo (family 06, model 0f) | 92 | * Xeon 5100 series and Core 2 Duo (family 06, model 0f) | |
93 | * Core 2 and Xeon (family 06, model 17) | 93 | * Core 2 and Xeon (family 06, model 17) | |
94 | * Atom (family 06, model 1c) | 94 | * Atom (family 06, model 1c) | |
95 | * | 95 | * | |
96 | * We'll also assume that it's safe on the Pentium, and | 96 | * We'll also assume that it's safe on the Pentium, and | |
97 | * that it's safe on P-II and P-III Xeons due to the | 97 | * that it's safe on P-II and P-III Xeons due to the | |
98 | * typical configuration of those systems. | 98 | * typical configuration of those systems. | |
99 | * | 99 | * | |
100 | */ | 100 | */ | |
101 | switch (CPUID_TO_BASEFAMILY(ci->ci_signature)) { | 101 | switch (CPUID_TO_BASEFAMILY(ci->ci_signature)) { | |
102 | case 0x05: | 102 | case 0x05: | |
103 | invariant = true; | 103 | invariant = true; | |
104 | break; | 104 | break; | |
105 | case 0x06: | 105 | case 0x06: | |
106 | invariant = CPUID_TO_MODEL(ci->ci_signature) == 0x0e || | 106 | invariant = CPUID_TO_MODEL(ci->ci_signature) == 0x0e || | |
107 | CPUID_TO_MODEL(ci->ci_signature) == 0x0f || | 107 | CPUID_TO_MODEL(ci->ci_signature) == 0x0f || | |
108 | CPUID_TO_MODEL(ci->ci_signature) == 0x17 || | 108 | CPUID_TO_MODEL(ci->ci_signature) == 0x17 || | |
109 | CPUID_TO_MODEL(ci->ci_signature) == 0x1c; | 109 | CPUID_TO_MODEL(ci->ci_signature) == 0x1c; | |
110 | break; | 110 | break; | |
111 | case 0x0f: | 111 | case 0x0f: | |
112 | invariant = CPUID_TO_MODEL(ci->ci_signature) >= 0x03; | 112 | invariant = CPUID_TO_MODEL(ci->ci_signature) >= 0x03; | |
113 | break; | 113 | break; | |
114 | } | 114 | } | |
115 | } else if (cpu_vendor == CPUVENDOR_AMD) { | 115 | } else if (cpu_vendor == CPUVENDOR_AMD) { | |
116 | /* | 116 | /* | |
117 | * TSC and Power Management Events on AMD Processors | 117 | * TSC and Power Management Events on AMD Processors | |
118 | * Nov 2, 2005 Rich Brunner, AMD Fellow | 118 | * Nov 2, 2005 Rich Brunner, AMD Fellow | |
119 | * http://lkml.org/lkml/2005/11/4/173 | 119 | * http://lkml.org/lkml/2005/11/4/173 | |
120 | * | 120 | * | |
121 | * See Appendix E.4.7 CPUID Fn8000_0007_EDX Advanced Power | 121 | * See Appendix E.4.7 CPUID Fn8000_0007_EDX Advanced Power | |
122 | * Management Features, AMD64 Architecture Programmer's | 122 | * Management Features, AMD64 Architecture Programmer's | |
123 | * Manual Volume 3: General-Purpose and System Instructions. | 123 | * Manual Volume 3: General-Purpose and System Instructions. | |
124 | * The check is done below. | 124 | * The check is done below. | |
125 | */ | 125 | */ | |
126 | } | 126 | } | |
127 | 127 | |||
128 | /* | 128 | /* | |
129 | * The best way to check whether the TSC counter is invariant or not | 129 | * The best way to check whether the TSC counter is invariant or not | |
130 | * is to check CPUID 80000007. | 130 | * is to check CPUID 80000007. | |
131 | */ | 131 | */ | |
132 | family = CPUID_TO_BASEFAMILY(ci->ci_signature); | 132 | family = CPUID_TO_BASEFAMILY(ci->ci_signature); | |
133 | if (((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | 133 | if (((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | |
134 | && ((family == 0x06) || (family == 0x0f))) { | 134 | && ((family == 0x06) || (family == 0x0f))) { | |
135 | x86_cpuid(0x80000000, descs); | 135 | x86_cpuid(0x80000000, descs); | |
136 | if (descs[0] >= 0x80000007) { | 136 | if (descs[0] >= 0x80000007) { | |
137 | x86_cpuid(0x80000007, descs); | 137 | x86_cpuid(0x80000007, descs); | |
138 | invariant = (descs[3] & CPUID_APM_TSC) != 0; | 138 | invariant = (descs[3] & CPUID_APM_ITSC) != 0; | |
139 | } | 139 | } | |
140 | } | 140 | } | |
141 | 141 | |||
142 | return invariant; | 142 | return invariant; | |
143 | } | 143 | } | |
144 | 144 | |||
145 | void | 145 | void | |
146 | tsc_tc_init(void) | 146 | tsc_tc_init(void) | |
147 | { | 147 | { | |
148 | struct cpu_info *ci; | 148 | struct cpu_info *ci; | |
149 | bool invariant; | 149 | bool invariant; | |
150 | 150 | |||
151 | if (!cpu_hascounter()) | 151 | if (!cpu_hascounter()) | |
152 | return; | 152 | return; | |
153 | 153 | |||
154 | ci = curcpu(); | 154 | ci = curcpu(); | |
155 | tsc_freq = ci->ci_data.cpu_cc_freq; | 155 | tsc_freq = ci->ci_data.cpu_cc_freq; | |
156 | tsc_good = (cpu_feature[0] & CPUID_MSR) != 0 && | 156 | tsc_good = (cpu_feature[0] & CPUID_MSR) != 0 && | |
157 | (rdmsr(MSR_TSC) != 0 || rdmsr(MSR_TSC) != 0); | 157 | (rdmsr(MSR_TSC) != 0 || rdmsr(MSR_TSC) != 0); | |
158 | 158 | |||
159 | invariant = tsc_is_invariant(); | 159 | invariant = tsc_is_invariant(); | |
160 | if (!invariant) { | 160 | if (!invariant) { | |
161 | aprint_debug("TSC not known invariant on this CPU\n"); | 161 | aprint_debug("TSC not known invariant on this CPU\n"); | |
162 | tsc_timecounter.tc_quality = -100; | 162 | tsc_timecounter.tc_quality = -100; | |
163 | } else if (tsc_drift_observed > tsc_drift_max) { | 163 | } else if (tsc_drift_observed > tsc_drift_max) { | |
164 | aprint_error("ERROR: %lld cycle TSC drift observed\n", | 164 | aprint_error("ERROR: %lld cycle TSC drift observed\n", | |
165 | (long long)tsc_drift_observed); | 165 | (long long)tsc_drift_observed); | |
166 | tsc_timecounter.tc_quality = -100; | 166 | tsc_timecounter.tc_quality = -100; | |
167 | invariant = false; | 167 | invariant = false; | |
168 | } | 168 | } | |
169 | 169 | |||
170 | if (tsc_freq != 0) { | 170 | if (tsc_freq != 0) { | |
171 | tsc_timecounter.tc_frequency = tsc_freq; | 171 | tsc_timecounter.tc_frequency = tsc_freq; | |
172 | tc_init(&tsc_timecounter); | 172 | tc_init(&tsc_timecounter); | |
173 | } | 173 | } | |
174 | } | 174 | } | |
175 | 175 | |||
176 | /* | 176 | /* | |
177 | * Record drift (in clock cycles). Called during AP startup. | 177 | * Record drift (in clock cycles). Called during AP startup. | |
178 | */ | 178 | */ | |
179 | void | 179 | void | |
180 | tsc_sync_drift(int64_t drift) | 180 | tsc_sync_drift(int64_t drift) | |
181 | { | 181 | { | |
182 | 182 | |||
183 | if (drift < 0) | 183 | if (drift < 0) | |
184 | drift = -drift; | 184 | drift = -drift; | |
185 | if (drift > tsc_drift_observed) | 185 | if (drift > tsc_drift_observed) | |
186 | tsc_drift_observed = drift; | 186 | tsc_drift_observed = drift; | |
187 | } | 187 | } | |
188 | 188 | |||
189 | /* | 189 | /* | |
190 | * Called during startup of APs, by the boot processor. Interrupts | 190 | * Called during startup of APs, by the boot processor. Interrupts | |
191 | * are disabled on entry. | 191 | * are disabled on entry. | |
192 | */ | 192 | */ | |
193 | static void | 193 | static void | |
194 | tsc_read_bp(struct cpu_info *ci, uint64_t *bptscp, uint64_t *aptscp) | 194 | tsc_read_bp(struct cpu_info *ci, uint64_t *bptscp, uint64_t *aptscp) | |
195 | { | 195 | { | |
196 | uint64_t bptsc; | 196 | uint64_t bptsc; | |
197 | 197 | |||
198 | if (atomic_swap_ptr(&tsc_sync_cpu, ci) != NULL) { | 198 | if (atomic_swap_ptr(&tsc_sync_cpu, ci) != NULL) { | |
199 | panic("tsc_sync_bp: 1"); | 199 | panic("tsc_sync_bp: 1"); | |
200 | } | 200 | } | |
201 | 201 | |||
202 | /* Flag it and read our TSC. */ | 202 | /* Flag it and read our TSC. */ | |
203 | atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC); | 203 | atomic_or_uint(&ci->ci_flags, CPUF_SYNCTSC); | |
204 | bptsc = cpu_counter_serializing() >> 1; | 204 | bptsc = cpu_counter_serializing() >> 1; | |
205 | 205 | |||
206 | /* Wait for remote to complete, and read ours again. */ | 206 | /* Wait for remote to complete, and read ours again. */ | |
207 | while ((ci->ci_flags & CPUF_SYNCTSC) != 0) { | 207 | while ((ci->ci_flags & CPUF_SYNCTSC) != 0) { | |
208 | __insn_barrier(); | 208 | __insn_barrier(); | |
209 | } | 209 | } | |
210 | bptsc += (cpu_counter_serializing() >> 1); | 210 | bptsc += (cpu_counter_serializing() >> 1); | |
211 | 211 | |||
212 | /* Wait for the results to come in. */ | 212 | /* Wait for the results to come in. */ | |
213 | while (tsc_sync_cpu == ci) { | 213 | while (tsc_sync_cpu == ci) { | |
214 | x86_pause(); | 214 | x86_pause(); | |
215 | } | 215 | } | |
216 | if (tsc_sync_cpu != NULL) { | 216 | if (tsc_sync_cpu != NULL) { | |
217 | panic("tsc_sync_bp: 2"); | 217 | panic("tsc_sync_bp: 2"); | |
218 | } | 218 | } | |
219 | 219 | |||
220 | *bptscp = bptsc; | 220 | *bptscp = bptsc; | |
221 | *aptscp = tsc_sync_val; | 221 | *aptscp = tsc_sync_val; | |
222 | } | 222 | } | |
223 | 223 | |||
224 | void | 224 | void | |
225 | tsc_sync_bp(struct cpu_info *ci) | 225 | tsc_sync_bp(struct cpu_info *ci) | |
226 | { | 226 | { | |
227 | uint64_t bptsc, aptsc; | 227 | uint64_t bptsc, aptsc; | |
228 | 228 | |||
229 | tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */ | 229 | tsc_read_bp(ci, &bptsc, &aptsc); /* discarded - cache effects */ | |
230 | tsc_read_bp(ci, &bptsc, &aptsc); | 230 | tsc_read_bp(ci, &bptsc, &aptsc); | |
231 | 231 | |||
232 | /* Compute final value to adjust for skew. */ | 232 | /* Compute final value to adjust for skew. */ | |
233 | ci->ci_data.cpu_cc_skew = bptsc - aptsc; | 233 | ci->ci_data.cpu_cc_skew = bptsc - aptsc; | |
234 | } | 234 | } | |
235 | 235 | |||
236 | /* | 236 | /* | |
237 | * Called during startup of AP, by the AP itself. Interrupts are | 237 | * Called during startup of AP, by the AP itself. Interrupts are | |
238 | * disabled on entry. | 238 | * disabled on entry. | |
239 | */ | 239 | */ | |
240 | static void | 240 | static void | |
241 | tsc_post_ap(struct cpu_info *ci) | 241 | tsc_post_ap(struct cpu_info *ci) | |
242 | { | 242 | { | |
243 | uint64_t tsc; | 243 | uint64_t tsc; | |
244 | 244 | |||
245 | /* Wait for go-ahead from primary. */ | 245 | /* Wait for go-ahead from primary. */ | |
246 | while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { | 246 | while ((ci->ci_flags & CPUF_SYNCTSC) == 0) { | |
247 | __insn_barrier(); | 247 | __insn_barrier(); | |
248 | } | 248 | } | |
249 | tsc = (cpu_counter_serializing() >> 1); | 249 | tsc = (cpu_counter_serializing() >> 1); | |
250 | 250 | |||
251 | /* Instruct primary to read its counter. */ | 251 | /* Instruct primary to read its counter. */ | |
252 | atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC); | 252 | atomic_and_uint(&ci->ci_flags, ~CPUF_SYNCTSC); | |
253 | tsc += (cpu_counter_serializing() >> 1); | 253 | tsc += (cpu_counter_serializing() >> 1); | |
254 | 254 | |||
255 | /* Post result. Ensure the whole value goes out atomically. */ | 255 | /* Post result. Ensure the whole value goes out atomically. */ | |
256 | (void)atomic_swap_64(&tsc_sync_val, tsc); | 256 | (void)atomic_swap_64(&tsc_sync_val, tsc); | |
257 | 257 | |||
258 | if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) { | 258 | if (atomic_swap_ptr(&tsc_sync_cpu, NULL) != ci) { | |
259 | panic("tsc_sync_ap"); | 259 | panic("tsc_sync_ap"); | |
260 | } | 260 | } | |
261 | } | 261 | } | |
262 | 262 | |||
263 | void | 263 | void | |
264 | tsc_sync_ap(struct cpu_info *ci) | 264 | tsc_sync_ap(struct cpu_info *ci) | |
265 | { | 265 | { | |
266 | 266 | |||
267 | tsc_post_ap(ci); | 267 | tsc_post_ap(ci); | |
268 | tsc_post_ap(ci); | 268 | tsc_post_ap(ci); | |
269 | } | 269 | } | |
270 | 270 | |||
271 | static void | 271 | static void | |
272 | tsc_apply_cpu(void *arg1, void *arg2) | 272 | tsc_apply_cpu(void *arg1, void *arg2) | |
273 | { | 273 | { | |
274 | bool enable = (bool)arg1; | 274 | bool enable = (bool)arg1; | |
275 | if (enable) { | 275 | if (enable) { | |
276 | lcr4(rcr4() & ~CR4_TSD); | 276 | lcr4(rcr4() & ~CR4_TSD); | |
277 | } else { | 277 | } else { | |
278 | lcr4(rcr4() | CR4_TSD); | 278 | lcr4(rcr4() | CR4_TSD); | |
279 | } | 279 | } | |
280 | } | 280 | } | |
281 | 281 | |||
282 | void | 282 | void | |
283 | tsc_user_enable(void) | 283 | tsc_user_enable(void) | |
284 | { | 284 | { | |
285 | uint64_t xc; | 285 | uint64_t xc; | |
286 | 286 | |||
287 | xc = xc_broadcast(0, tsc_apply_cpu, (void *)true, NULL); | 287 | xc = xc_broadcast(0, tsc_apply_cpu, (void *)true, NULL); | |
288 | xc_wait(xc); | 288 | xc_wait(xc); | |
289 | } | 289 | } | |
290 | 290 | |||
291 | void | 291 | void | |
292 | tsc_user_disable(void) | 292 | tsc_user_disable(void) | |
293 | { | 293 | { | |
294 | uint64_t xc; | 294 | uint64_t xc; | |
295 | 295 | |||
296 | xc = xc_broadcast(0, tsc_apply_cpu, (void *)false, NULL); | 296 | xc = xc_broadcast(0, tsc_apply_cpu, (void *)false, NULL); | |
297 | xc_wait(xc); | 297 | xc_wait(xc); | |
298 | } | 298 | } | |
299 | 299 | |||
300 | uint64_t | 300 | uint64_t | |
301 | cpu_frequency(struct cpu_info *ci) | 301 | cpu_frequency(struct cpu_info *ci) | |
302 | { | 302 | { | |
303 | 303 | |||
304 | return ci->ci_data.cpu_cc_freq; | 304 | return ci->ci_data.cpu_cc_freq; | |
305 | } | 305 | } | |
306 | 306 | |||
307 | int | 307 | int | |
308 | cpu_hascounter(void) | 308 | cpu_hascounter(void) | |
309 | { | 309 | { | |
310 | 310 | |||
311 | return cpu_feature[0] & CPUID_TSC; | 311 | return cpu_feature[0] & CPUID_TSC; | |
312 | } | 312 | } | |
313 | 313 | |||
314 | uint64_t | 314 | uint64_t | |
315 | cpu_counter_serializing(void) | 315 | cpu_counter_serializing(void) | |
316 | { | 316 | { | |
317 | if (tsc_good) | 317 | if (tsc_good) | |
318 | return rdmsr(MSR_TSC); | 318 | return rdmsr(MSR_TSC); | |
319 | else | 319 | else | |
320 | return cpu_counter(); | 320 | return cpu_counter(); | |
321 | } | 321 | } |
--- src/usr.sbin/cpuctl/arch/i386.c 2019/11/19 13:15:57 1.104.2.4
+++ src/usr.sbin/cpuctl/arch/i386.c 2020/04/14 17:15:02 1.104.2.5
@@ -1,2628 +1,2622 @@ | @@ -1,2628 +1,2622 @@ | |||
1 | /* $NetBSD: i386.c,v 1.104.2.4 2019/11/19 13:15:57 martin Exp $ */ | 1 | /* $NetBSD: i386.c,v 1.104.2.5 2020/04/14 17:15:02 martin 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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 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 | 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 | /*- | 32 | /*- | |
33 | * Copyright (c)2008 YAMAMOTO Takashi, | 33 | * Copyright (c)2008 YAMAMOTO Takashi, | |
34 | * All rights reserved. | 34 | * All rights reserved. | |
35 | * | 35 | * | |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without | |
37 | * modification, are permitted provided that the following conditions | 37 | * modification, are permitted provided that the following conditions | |
38 | * are met: | 38 | * are met: | |
39 | * 1. Redistributions of source code must retain the above copyright | 39 | * 1. Redistributions of source code must retain the above copyright | |
40 | * notice, this list of conditions and the following disclaimer. | 40 | * notice, this list of conditions and the following disclaimer. | |
41 | * 2. Redistributions in binary form must reproduce the above copyright | 41 | * 2. Redistributions in binary form must reproduce the above copyright | |
42 | * notice, this list of conditions and the following disclaimer in the | 42 | * notice, this list of conditions and the following disclaimer in the | |
43 | * documentation and/or other materials provided with the distribution. | 43 | * documentation and/or other materials provided with the distribution. | |
44 | * | 44 | * | |
45 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | 45 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 46 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
55 | * SUCH DAMAGE. | 55 | * SUCH DAMAGE. | |
56 | */ | 56 | */ | |
57 | 57 | |||
58 | #include <sys/cdefs.h> | 58 | #include <sys/cdefs.h> | |
59 | #ifndef lint | 59 | #ifndef lint | |
60 | __RCSID("$NetBSD: i386.c,v 1.104.2.4 2019/11/19 13:15:57 martin Exp $"); | 60 | __RCSID("$NetBSD: i386.c,v 1.104.2.5 2020/04/14 17:15:02 martin Exp $"); | |
61 | #endif /* not lint */ | 61 | #endif /* not lint */ | |
62 | 62 | |||
63 | #include <sys/types.h> | 63 | #include <sys/types.h> | |
64 | #include <sys/param.h> | 64 | #include <sys/param.h> | |
65 | #include <sys/bitops.h> | 65 | #include <sys/bitops.h> | |
66 | #include <sys/sysctl.h> | 66 | #include <sys/sysctl.h> | |
67 | #include <sys/ioctl.h> | 67 | #include <sys/ioctl.h> | |
68 | #include <sys/cpuio.h> | 68 | #include <sys/cpuio.h> | |
69 | 69 | |||
70 | #include <errno.h> | 70 | #include <errno.h> | |
71 | #include <string.h> | 71 | #include <string.h> | |
72 | #include <stdio.h> | 72 | #include <stdio.h> | |
73 | #include <stdlib.h> | 73 | #include <stdlib.h> | |
74 | #include <err.h> | 74 | #include <err.h> | |
75 | #include <assert.h> | 75 | #include <assert.h> | |
76 | #include <math.h> | 76 | #include <math.h> | |
77 | #include <util.h> | 77 | #include <util.h> | |
78 | 78 | |||
79 | #include <machine/specialreg.h> | 79 | #include <machine/specialreg.h> | |
80 | #include <machine/cpu.h> | 80 | #include <machine/cpu.h> | |
81 | 81 | |||
82 | #include <x86/cpuvar.h> | 82 | #include <x86/cpuvar.h> | |
83 | #include <x86/cputypes.h> | 83 | #include <x86/cputypes.h> | |
84 | #include <x86/cacheinfo.h> | 84 | #include <x86/cacheinfo.h> | |
85 | #include <x86/cpu_ucode.h> | 85 | #include <x86/cpu_ucode.h> | |
86 | 86 | |||
87 | #include "../cpuctl.h" | 87 | #include "../cpuctl.h" | |
88 | #include "cpuctl_i386.h" | 88 | #include "cpuctl_i386.h" | |
89 | 89 | |||
90 | /* Size of buffer for printing humanized numbers */ | 90 | /* Size of buffer for printing humanized numbers */ | |
91 | #define HUMAN_BUFSIZE sizeof("999KB") | 91 | #define HUMAN_BUFSIZE sizeof("999KB") | |
92 | 92 | |||
93 | struct cpu_info { | 93 | struct cpu_info { | |
94 | const char *ci_dev; | 94 | const char *ci_dev; | |
95 | int32_t ci_cpu_type; /* for cpu's without cpuid */ | 95 | int32_t ci_cpu_type; /* for cpu's without cpuid */ | |
96 | int32_t ci_cpuid_level; /* highest cpuid supported */ | 96 | int32_t ci_cpuid_level; /* highest cpuid supported */ | |
97 | uint32_t ci_cpuid_extlevel; /* highest cpuid extended func lv */ | 97 | uint32_t ci_cpuid_extlevel; /* highest cpuid extended func lv */ | |
98 | uint32_t ci_signature; /* X86 cpuid type */ | 98 | uint32_t ci_signature; /* X86 cpuid type */ | |
99 | uint32_t ci_family; /* from ci_signature */ | 99 | uint32_t ci_family; /* from ci_signature */ | |
100 | uint32_t ci_model; /* from ci_signature */ | 100 | uint32_t ci_model; /* from ci_signature */ | |
101 | uint32_t ci_feat_val[10]; /* X86 CPUID feature bits | 101 | uint32_t ci_feat_val[10]; /* X86 CPUID feature bits | |
102 | * [0] basic features %edx | 102 | * [0] basic features %edx | |
103 | * [1] basic features %ecx | 103 | * [1] basic features %ecx | |
104 | * [2] extended features %edx | 104 | * [2] extended features %edx | |
105 | * [3] extended features %ecx | 105 | * [3] extended features %ecx | |
106 | * [4] VIA padlock features | 106 | * [4] VIA padlock features | |
107 | * [5] structure ext. feat. %ebx | 107 | * [5] structure ext. feat. %ebx | |
108 | * [6] structure ext. feat. %ecx | 108 | * [6] structure ext. feat. %ecx | |
109 | * [7] structure ext. feat. %edx | 109 | * [7] structure ext. feat. %edx | |
110 | * [8] XCR0 bits (d:0 %eax) | 110 | * [8] XCR0 bits (d:0 %eax) | |
111 | * [9] xsave flags (d:1 %eax) | 111 | * [9] xsave flags (d:1 %eax) | |
112 | */ | 112 | */ | |
113 | uint32_t ci_cpu_class; /* CPU class */ | 113 | uint32_t ci_cpu_class; /* CPU class */ | |
114 | uint32_t ci_brand_id; /* Intel brand id */ | 114 | uint32_t ci_brand_id; /* Intel brand id */ | |
115 | uint32_t ci_vendor[4]; /* vendor string */ | 115 | uint32_t ci_vendor[4]; /* vendor string */ | |
116 | uint32_t ci_cpu_serial[3]; /* PIII serial number */ | 116 | uint32_t ci_cpu_serial[3]; /* PIII serial number */ | |
117 | uint64_t ci_tsc_freq; /* cpu cycles/second */ | 117 | uint64_t ci_tsc_freq; /* cpu cycles/second */ | |
118 | uint8_t ci_packageid; | 118 | uint8_t ci_packageid; | |
119 | uint8_t ci_coreid; | 119 | uint8_t ci_coreid; | |
120 | uint8_t ci_smtid; | 120 | uint8_t ci_smtid; | |
121 | uint32_t ci_initapicid; | 121 | uint32_t ci_initapicid; | |
122 | uint32_t ci_max_ext_cpuid; | |||
123 | 122 | |||
124 | uint32_t ci_cur_xsave; | 123 | uint32_t ci_cur_xsave; | |
125 | uint32_t ci_max_xsave; | 124 | uint32_t ci_max_xsave; | |
126 | 125 | |||
127 | struct x86_cache_info ci_cinfo[CAI_COUNT]; | 126 | struct x86_cache_info ci_cinfo[CAI_COUNT]; | |
128 | void (*ci_info)(struct cpu_info *); | 127 | void (*ci_info)(struct cpu_info *); | |
129 | }; | 128 | }; | |
130 | 129 | |||
131 | struct cpu_nocpuid_nameclass { | 130 | struct cpu_nocpuid_nameclass { | |
132 | int cpu_vendor; | 131 | int cpu_vendor; | |
133 | const char *cpu_vendorname; | 132 | const char *cpu_vendorname; | |
134 | const char *cpu_name; | 133 | const char *cpu_name; | |
135 | int cpu_class; | 134 | int cpu_class; | |
136 | void (*cpu_setup)(struct cpu_info *); | 135 | void (*cpu_setup)(struct cpu_info *); | |
137 | void (*cpu_cacheinfo)(struct cpu_info *); | 136 | void (*cpu_cacheinfo)(struct cpu_info *); | |
138 | void (*cpu_info)(struct cpu_info *); | 137 | void (*cpu_info)(struct cpu_info *); | |
139 | }; | 138 | }; | |
140 | 139 | |||
141 | struct cpu_cpuid_nameclass { | 140 | struct cpu_cpuid_nameclass { | |
142 | const char *cpu_id; | 141 | const char *cpu_id; | |
143 | int cpu_vendor; | 142 | int cpu_vendor; | |
144 | const char *cpu_vendorname; | 143 | const char *cpu_vendorname; | |
145 | struct cpu_cpuid_family { | 144 | struct cpu_cpuid_family { | |
146 | int cpu_class; | 145 | int cpu_class; | |
147 | const char *cpu_models[256]; | 146 | const char *cpu_models[256]; | |
148 | const char *cpu_model_default; | 147 | const char *cpu_model_default; | |
149 | void (*cpu_setup)(struct cpu_info *); | 148 | void (*cpu_setup)(struct cpu_info *); | |
150 | void (*cpu_probe)(struct cpu_info *); | 149 | void (*cpu_probe)(struct cpu_info *); | |
151 | void (*cpu_info)(struct cpu_info *); | 150 | void (*cpu_info)(struct cpu_info *); | |
152 | } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; | 151 | } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; | |
153 | }; | 152 | }; | |
154 | 153 | |||
155 | static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; | 154 | static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO; | |
156 | 155 | |||
157 | /* | 156 | /* | |
158 | * Map Brand ID from cpuid instruction to brand name. | 157 | * Map Brand ID from cpuid instruction to brand name. | |
159 | * Source: Table 3-24, Mapping of Brand Indices; and Intel 64 and IA-32 | 158 | * Source: Table 3-24, Mapping of Brand Indices; and Intel 64 and IA-32 | |
160 | * Processor Brand Strings, Chapter 3 in "Intel (R) 64 and IA-32 | 159 | * Processor Brand Strings, Chapter 3 in "Intel (R) 64 and IA-32 | |
161 | * Architectures Software Developer's Manual, Volume 2A". | 160 | * Architectures Software Developer's Manual, Volume 2A". | |
162 | */ | 161 | */ | |
163 | static const char * const i386_intel_brand[] = { | 162 | static const char * const i386_intel_brand[] = { | |
164 | "", /* Unsupported */ | 163 | "", /* Unsupported */ | |
165 | "Celeron", /* Intel (R) Celeron (TM) processor */ | 164 | "Celeron", /* Intel (R) Celeron (TM) processor */ | |
166 | "Pentium III", /* Intel (R) Pentium (R) III processor */ | 165 | "Pentium III", /* Intel (R) Pentium (R) III processor */ | |
167 | "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */ | 166 | "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */ | |
168 | "Pentium III", /* Intel (R) Pentium (R) III processor */ | 167 | "Pentium III", /* Intel (R) Pentium (R) III processor */ | |
169 | "", /* 0x05: Reserved */ | 168 | "", /* 0x05: Reserved */ | |
170 | "Mobile Pentium III",/* Mobile Intel (R) Pentium (R) III processor-M */ | 169 | "Mobile Pentium III",/* Mobile Intel (R) Pentium (R) III processor-M */ | |
171 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | 170 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | |
172 | "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ | 171 | "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ | |
173 | "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ | 172 | "Pentium 4", /* Intel (R) Pentium (R) 4 processor */ | |
174 | "Celeron", /* Intel (R) Celeron (TM) processor */ | 173 | "Celeron", /* Intel (R) Celeron (TM) processor */ | |
175 | "Xeon", /* Intel (R) Xeon (TM) processor */ | 174 | "Xeon", /* Intel (R) Xeon (TM) processor */ | |
176 | "Xeon MP", /* Intel (R) Xeon (TM) processor MP */ | 175 | "Xeon MP", /* Intel (R) Xeon (TM) processor MP */ | |
177 | "", /* 0x0d: Reserved */ | 176 | "", /* 0x0d: Reserved */ | |
178 | "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */ | 177 | "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */ | |
179 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | 178 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | |
180 | "", /* 0x10: Reserved */ | 179 | "", /* 0x10: Reserved */ | |
181 | "Mobile Genuine", /* Moblie Genuine Intel (R) processor */ | 180 | "Mobile Genuine", /* Moblie Genuine Intel (R) processor */ | |
182 | "Celeron M", /* Intel (R) Celeron (R) M processor */ | 181 | "Celeron M", /* Intel (R) Celeron (R) M processor */ | |
183 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | 182 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | |
184 | "Celeron", /* Intel (R) Celeron (R) processor */ | 183 | "Celeron", /* Intel (R) Celeron (R) processor */ | |
185 | "Mobile Genuine", /* Moblie Genuine Intel (R) processor */ | 184 | "Mobile Genuine", /* Moblie Genuine Intel (R) processor */ | |
186 | "Pentium M", /* Intel (R) Pentium (R) M processor */ | 185 | "Pentium M", /* Intel (R) Pentium (R) M processor */ | |
187 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | 186 | "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */ | |
188 | }; | 187 | }; | |
189 | 188 | |||
190 | /* | 189 | /* | |
191 | * AMD processors don't have Brand IDs, so we need these names for probe. | 190 | * AMD processors don't have Brand IDs, so we need these names for probe. | |
192 | */ | 191 | */ | |
193 | static const char * const amd_brand[] = { | 192 | static const char * const amd_brand[] = { | |
194 | "", | 193 | "", | |
195 | "Duron", /* AMD Duron(tm) */ | 194 | "Duron", /* AMD Duron(tm) */ | |
196 | "MP", /* AMD Athlon(tm) MP */ | 195 | "MP", /* AMD Athlon(tm) MP */ | |
197 | "XP", /* AMD Athlon(tm) XP */ | 196 | "XP", /* AMD Athlon(tm) XP */ | |
198 | "4" /* AMD Athlon(tm) 4 */ | 197 | "4" /* AMD Athlon(tm) 4 */ | |
199 | }; | 198 | }; | |
200 | 199 | |||
201 | static int cpu_vendor; | 200 | static int cpu_vendor; | |
202 | static char cpu_brand_string[49]; | 201 | static char cpu_brand_string[49]; | |
203 | static char amd_brand_name[48]; | 202 | static char amd_brand_name[48]; | |
204 | static int use_pae, largepagesize; | 203 | static int use_pae, largepagesize; | |
205 | 204 | |||
206 | /* Setup functions */ | 205 | /* Setup functions */ | |
207 | static void disable_tsc(struct cpu_info *); | 206 | static void disable_tsc(struct cpu_info *); | |
208 | static void amd_family5_setup(struct cpu_info *); | 207 | static void amd_family5_setup(struct cpu_info *); | |
209 | static void cyrix6x86_cpu_setup(struct cpu_info *); | 208 | static void cyrix6x86_cpu_setup(struct cpu_info *); | |
210 | static void winchip_cpu_setup(struct cpu_info *); | 209 | static void winchip_cpu_setup(struct cpu_info *); | |
211 | /* Brand/Model name functions */ | 210 | /* Brand/Model name functions */ | |
212 | static const char *intel_family6_name(struct cpu_info *); | 211 | static const char *intel_family6_name(struct cpu_info *); | |
213 | static const char *amd_amd64_name(struct cpu_info *); | 212 | static const char *amd_amd64_name(struct cpu_info *); | |
214 | /* Probe functions */ | 213 | /* Probe functions */ | |
215 | static void amd_family6_probe(struct cpu_info *); | 214 | static void amd_family6_probe(struct cpu_info *); | |
216 | static void powernow_probe(struct cpu_info *); | 215 | static void powernow_probe(struct cpu_info *); | |
217 | static void intel_family_new_probe(struct cpu_info *); | 216 | static void intel_family_new_probe(struct cpu_info *); | |
218 | static void via_cpu_probe(struct cpu_info *); | 217 | static void via_cpu_probe(struct cpu_info *); | |
219 | /* (Cache) Info functions */ | 218 | /* (Cache) Info functions */ | |
220 | static void cpu_dcp_cacheinfo(struct cpu_info *, uint32_t); | 219 | static void cpu_dcp_cacheinfo(struct cpu_info *, uint32_t); | |
221 | static void intel_cpu_cacheinfo(struct cpu_info *); | 220 | static void intel_cpu_cacheinfo(struct cpu_info *); | |
222 | static void amd_cpu_cacheinfo(struct cpu_info *); | 221 | static void amd_cpu_cacheinfo(struct cpu_info *); | |
223 | static void via_cpu_cacheinfo(struct cpu_info *); | 222 | static void via_cpu_cacheinfo(struct cpu_info *); | |
224 | static void tmx86_get_longrun_status(u_int *, u_int *, u_int *); | 223 | static void tmx86_get_longrun_status(u_int *, u_int *, u_int *); | |
225 | static void transmeta_cpu_info(struct cpu_info *); | 224 | static void transmeta_cpu_info(struct cpu_info *); | |
226 | /* Common functions */ | 225 | /* Common functions */ | |
227 | static void cpu_probe_base_features(struct cpu_info *, const char *); | 226 | static void cpu_probe_base_features(struct cpu_info *, const char *); | |
228 | static void cpu_probe_hv_features(struct cpu_info *, const char *); | 227 | static void cpu_probe_hv_features(struct cpu_info *, const char *); | |
229 | static void cpu_probe_features(struct cpu_info *); | 228 | static void cpu_probe_features(struct cpu_info *); | |
230 | static void print_bits(const char *, const char *, const char *, uint32_t); | 229 | static void print_bits(const char *, const char *, const char *, uint32_t); | |
231 | static void identifycpu_cpuids(struct cpu_info *); | 230 | static void identifycpu_cpuids(struct cpu_info *); | |
232 | static const struct x86_cache_info *cache_info_lookup( | 231 | static const struct x86_cache_info *cache_info_lookup( | |
233 | const struct x86_cache_info *, uint8_t); | 232 | const struct x86_cache_info *, uint8_t); | |
234 | static const char *print_cache_config(struct cpu_info *, int, const char *, | 233 | static const char *print_cache_config(struct cpu_info *, int, const char *, | |
235 | const char *); | 234 | const char *); | |
236 | static const char *print_tlb_config(struct cpu_info *, int, const char *, | 235 | static const char *print_tlb_config(struct cpu_info *, int, const char *, | |
237 | const char *); | 236 | const char *); | |
238 | static void x86_print_cache_and_tlb_info(struct cpu_info *); | 237 | static void x86_print_cache_and_tlb_info(struct cpu_info *); | |
239 | 238 | |||
240 | /* | 239 | /* | |
241 | * Note: these are just the ones that may not have a cpuid instruction. | 240 | * Note: these are just the ones that may not have a cpuid instruction. | |
242 | * We deal with the rest in a different way. | 241 | * We deal with the rest in a different way. | |
243 | */ | 242 | */ | |
244 | const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = { | 243 | const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = { | |
245 | { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386, | 244 | { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386, | |
246 | NULL, NULL, NULL }, /* CPU_386SX */ | 245 | NULL, NULL, NULL }, /* CPU_386SX */ | |
247 | { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386, | 246 | { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386, | |
248 | NULL, NULL, NULL }, /* CPU_386 */ | 247 | NULL, NULL, NULL }, /* CPU_386 */ | |
249 | { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486, | 248 | { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486, | |
250 | NULL, NULL, NULL }, /* CPU_486SX */ | 249 | NULL, NULL, NULL }, /* CPU_486SX */ | |
251 | { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486, | 250 | { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486, | |
252 | NULL, NULL, NULL }, /* CPU_486 */ | 251 | NULL, NULL, NULL }, /* CPU_486 */ | |
253 | { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486, | 252 | { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486, | |
254 | NULL, NULL, NULL }, /* CPU_486DLC */ | 253 | NULL, NULL, NULL }, /* CPU_486DLC */ | |
255 | { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486, | 254 | { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486, | |
256 | NULL, NULL, NULL }, /* CPU_6x86 */ | 255 | NULL, NULL, NULL }, /* CPU_6x86 */ | |
257 | { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386, | 256 | { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386, | |
258 | NULL, NULL, NULL }, /* CPU_NX586 */ | 257 | NULL, NULL, NULL }, /* CPU_NX586 */ | |
259 | }; | 258 | }; | |
260 | 259 | |||
261 | const char *classnames[] = { | 260 | const char *classnames[] = { | |
262 | "386", | 261 | "386", | |
263 | "486", | 262 | "486", | |
264 | "586", | 263 | "586", | |
265 | "686" | 264 | "686" | |
266 | }; | 265 | }; | |
267 | 266 | |||
268 | const char *modifiers[] = { | 267 | const char *modifiers[] = { | |
269 | "", | 268 | "", | |
270 | "OverDrive", | 269 | "OverDrive", | |
271 | "Dual", | 270 | "Dual", | |
272 | "" | 271 | "" | |
273 | }; | 272 | }; | |
274 | 273 | |||
275 | const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { | 274 | const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { | |
276 | { | 275 | { | |
277 | /* | 276 | /* | |
278 | * For Intel processors, check Chapter 35Model-specific | 277 | * For Intel processors, check Chapter 35Model-specific | |
279 | * registers (MSRS), in "Intel (R) 64 and IA-32 Architectures | 278 | * registers (MSRS), in "Intel (R) 64 and IA-32 Architectures | |
280 | * Software Developer's Manual, Volume 3C". | 279 | * Software Developer's Manual, Volume 3C". | |
281 | */ | 280 | */ | |
282 | "GenuineIntel", | 281 | "GenuineIntel", | |
283 | CPUVENDOR_INTEL, | 282 | CPUVENDOR_INTEL, | |
284 | "Intel", | 283 | "Intel", | |
285 | /* Family 4 */ | 284 | /* Family 4 */ | |
286 | { { | 285 | { { | |
287 | CPUCLASS_486, | 286 | CPUCLASS_486, | |
288 | { | 287 | { | |
289 | "486DX", "486DX", "486SX", "486DX2", "486SL", | 288 | "486DX", "486DX", "486SX", "486DX2", "486SL", | |
290 | "486SX2", 0, "486DX2 W/B Enhanced", | 289 | "486SX2", 0, "486DX2 W/B Enhanced", | |
291 | "486DX4", 0, 0, 0, 0, 0, 0, 0, | 290 | "486DX4", 0, 0, 0, 0, 0, 0, 0, | |
292 | }, | 291 | }, | |
293 | "486", /* Default */ | 292 | "486", /* Default */ | |
294 | NULL, | 293 | NULL, | |
295 | NULL, | 294 | NULL, | |
296 | intel_cpu_cacheinfo, | 295 | intel_cpu_cacheinfo, | |
297 | }, | 296 | }, | |
298 | /* Family 5 */ | 297 | /* Family 5 */ | |
299 | { | 298 | { | |
300 | CPUCLASS_586, | 299 | CPUCLASS_586, | |
301 | { | 300 | { | |
302 | "Pentium (P5 A-step)", "Pentium (P5)", | 301 | "Pentium (P5 A-step)", "Pentium (P5)", | |
303 | "Pentium (P54C)", "Pentium (P24T)", | 302 | "Pentium (P54C)", "Pentium (P24T)", | |
304 | "Pentium/MMX", "Pentium", 0, | 303 | "Pentium/MMX", "Pentium", 0, | |
305 | "Pentium (P54C)", "Pentium/MMX (Tillamook)", | 304 | "Pentium (P54C)", "Pentium/MMX (Tillamook)", | |
306 | "Quark X1000", 0, 0, 0, 0, 0, 0, | 305 | "Quark X1000", 0, 0, 0, 0, 0, 0, | |
307 | }, | 306 | }, | |
308 | "Pentium", /* Default */ | 307 | "Pentium", /* Default */ | |
309 | NULL, | 308 | NULL, | |
310 | NULL, | 309 | NULL, | |
311 | intel_cpu_cacheinfo, | 310 | intel_cpu_cacheinfo, | |
312 | }, | 311 | }, | |
313 | /* Family 6 */ | 312 | /* Family 6 */ | |
314 | { | 313 | { | |
315 | CPUCLASS_686, | 314 | CPUCLASS_686, | |
316 | { | 315 | { | |
317 | [0x00] = "Pentium Pro (A-step)", | 316 | [0x00] = "Pentium Pro (A-step)", | |
318 | [0x01] = "Pentium Pro", | 317 | [0x01] = "Pentium Pro", | |
319 | [0x03] = "Pentium II (Klamath)", | 318 | [0x03] = "Pentium II (Klamath)", | |
320 | [0x04] = "Pentium Pro", | 319 | [0x04] = "Pentium Pro", | |
321 | [0x05] = "Pentium II/Celeron (Deschutes)", | 320 | [0x05] = "Pentium II/Celeron (Deschutes)", | |
322 | [0x06] = "Celeron (Mendocino)", | 321 | [0x06] = "Celeron (Mendocino)", | |
323 | [0x07] = "Pentium III (Katmai)", | 322 | [0x07] = "Pentium III (Katmai)", | |
324 | [0x08] = "Pentium III (Coppermine)", | 323 | [0x08] = "Pentium III (Coppermine)", | |
325 | [0x09] = "Pentium M (Banias)", | 324 | [0x09] = "Pentium M (Banias)", | |
326 | [0x0a] = "Pentium III Xeon (Cascades)", | 325 | [0x0a] = "Pentium III Xeon (Cascades)", | |
327 | [0x0b] = "Pentium III (Tualatin)", | 326 | [0x0b] = "Pentium III (Tualatin)", | |
328 | [0x0d] = "Pentium M (Dothan)", | 327 | [0x0d] = "Pentium M (Dothan)", | |
329 | [0x0e] = "Pentium Core Duo, Core solo", | 328 | [0x0e] = "Pentium Core Duo, Core solo", | |
330 | [0x0f] = "Xeon 30xx, 32xx, 51xx, 53xx, 73xx, " | 329 | [0x0f] = "Xeon 30xx, 32xx, 51xx, 53xx, 73xx, " | |
331 | "Core 2 Quad 6xxx, " | 330 | "Core 2 Quad 6xxx, " | |
332 | "Core 2 Extreme 6xxx, " | 331 | "Core 2 Extreme 6xxx, " | |
333 | "Core 2 Duo 4xxx, 5xxx, 6xxx, 7xxx " | 332 | "Core 2 Duo 4xxx, 5xxx, 6xxx, 7xxx " | |
334 | "and Pentium DC", | 333 | "and Pentium DC", | |
335 | [0x15] = "EP80579 Integrated Processor", | 334 | [0x15] = "EP80579 Integrated Processor", | |
336 | [0x16] = "Celeron (45nm)", | 335 | [0x16] = "Celeron (45nm)", | |
337 | [0x17] = "Xeon 31xx, 33xx, 52xx, 54xx, " | 336 | [0x17] = "Xeon 31xx, 33xx, 52xx, 54xx, " | |
338 | "Core 2 Quad 8xxx and 9xxx", | 337 | "Core 2 Quad 8xxx and 9xxx", | |
339 | [0x1a] = "Core i7, Xeon 34xx, 35xx and 55xx " | 338 | [0x1a] = "Core i7, Xeon 34xx, 35xx and 55xx " | |
340 | "(Nehalem)", | 339 | "(Nehalem)", | |
341 | [0x1c] = "45nm Atom Family", | 340 | [0x1c] = "45nm Atom Family", | |
342 | [0x1d] = "XeonMP 74xx (Nehalem)", | 341 | [0x1d] = "XeonMP 74xx (Nehalem)", | |
343 | [0x1e] = "Core i7 and i5", | 342 | [0x1e] = "Core i7 and i5", | |
344 | [0x1f] = "Core i7 and i5", | 343 | [0x1f] = "Core i7 and i5", | |
345 | [0x25] = "Xeon 36xx & 56xx, i7, i5 and i3", | 344 | [0x25] = "Xeon 36xx & 56xx, i7, i5 and i3", | |
346 | [0x26] = "Atom Family", | 345 | [0x26] = "Atom Family", | |
347 | [0x27] = "Atom Family", | 346 | [0x27] = "Atom Family", | |
348 | [0x2a] = "Xeon E3-12xx, 2nd gen i7, i5, " | 347 | [0x2a] = "Xeon E3-12xx, 2nd gen i7, i5, " | |
349 | "i3 2xxx", | 348 | "i3 2xxx", | |
350 | [0x2c] = "Xeon 36xx & 56xx, i7, i5 and i3", | 349 | [0x2c] = "Xeon 36xx & 56xx, i7, i5 and i3", | |
351 | [0x2d] = "Xeon E5 Sandy Bridge family, " | 350 | [0x2d] = "Xeon E5 Sandy Bridge family, " | |
352 | "Core i7-39xx Extreme", | 351 | "Core i7-39xx Extreme", | |
353 | [0x2e] = "Xeon 75xx & 65xx", | 352 | [0x2e] = "Xeon 75xx & 65xx", | |
354 | [0x2f] = "Xeon E7 family", | 353 | [0x2f] = "Xeon E7 family", | |
355 | [0x35] = "Atom Family", | 354 | [0x35] = "Atom Family", | |
356 | [0x36] = "Atom S1000", | 355 | [0x36] = "Atom S1000", | |
357 | [0x37] = "Atom E3000, Z3[67]00", | 356 | [0x37] = "Atom E3000, Z3[67]00", | |
358 | [0x3a] = "Xeon E3-1200v2 and 3rd gen core, " | 357 | [0x3a] = "Xeon E3-1200v2 and 3rd gen core, " | |
359 | "Ivy Bridge", | 358 | "Ivy Bridge", | |
360 | [0x3c] = "4th gen Core, Xeon E3-12xx v3 " | 359 | [0x3c] = "4th gen Core, Xeon E3-12xx v3 " | |
361 | "(Haswell)", | 360 | "(Haswell)", | |
362 | [0x3d] = "Core M-5xxx, 5th gen Core (Broadwell)", | 361 | [0x3d] = "Core M-5xxx, 5th gen Core (Broadwell)", | |
363 | [0x3e] = "Xeon E5/E7 v2 (Ivy Bridge-E), " | 362 | [0x3e] = "Xeon E5/E7 v2 (Ivy Bridge-E), " | |
364 | "Core i7-49xx Extreme", | 363 | "Core i7-49xx Extreme", | |
365 | [0x3f] = "Xeon E5-4600/2600/1600 v3, Xeon E7 v3 (Haswell-E), " | 364 | [0x3f] = "Xeon E5-4600/2600/1600 v3, Xeon E7 v3 (Haswell-E), " | |
366 | "Core i7-59xx Extreme", | 365 | "Core i7-59xx Extreme", | |
367 | [0x45] = "4th gen Core, Xeon E3-12xx v3 " | 366 | [0x45] = "4th gen Core, Xeon E3-12xx v3 " | |
368 | "(Haswell)", | 367 | "(Haswell)", | |
369 | [0x46] = "4th gen Core, Xeon E3-12xx v3 " | 368 | [0x46] = "4th gen Core, Xeon E3-12xx v3 " | |
370 | "(Haswell)", | 369 | "(Haswell)", | |
371 | [0x47] = "5th gen Core, Xeon E3-1200 v4 (Broadwell)", | 370 | [0x47] = "5th gen Core, Xeon E3-1200 v4 (Broadwell)", | |
372 | [0x4a] = "Atom Z3400", | 371 | [0x4a] = "Atom Z3400", | |
373 | [0x4c] = "Atom X[57]-Z8000 (Airmont)", | 372 | [0x4c] = "Atom X[57]-Z8000 (Airmont)", | |
374 | [0x4d] = "Atom C2000", | 373 | [0x4d] = "Atom C2000", | |
375 | [0x4e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)", | 374 | [0x4e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)", | |
376 | [0x4f] = "Xeon E[57] v4 (Broadwell), Core i7-69xx Extreme", | 375 | [0x4f] = "Xeon E[57] v4 (Broadwell), Core i7-69xx Extreme", | |
377 | [0x55] = "Xeon Scalable (Skylake, Cascade Lake, Copper Lake)", | 376 | [0x55] = "Xeon Scalable (Skylake, Cascade Lake, Copper Lake)", | |
378 | [0x56] = "Xeon D-1500 (Broadwell)", | 377 | [0x56] = "Xeon D-1500 (Broadwell)", | |
379 | [0x57] = "Xeon Phi [357]200 (Knights Landing)", | 378 | [0x57] = "Xeon Phi [357]200 (Knights Landing)", | |
380 | [0x5a] = "Atom E3500", | 379 | [0x5a] = "Atom E3500", | |
381 | [0x5c] = "Atom (Goldmont)", | 380 | [0x5c] = "Atom (Goldmont)", | |
382 | [0x5d] = "Atom X3-C3000 (Silvermont)", | 381 | [0x5d] = "Atom X3-C3000 (Silvermont)", | |
383 | [0x5e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)", | 382 | [0x5e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)", | |
384 | [0x5f] = "Atom (Goldmont, Denverton)", | 383 | [0x5f] = "Atom (Goldmont, Denverton)", | |
385 | [0x66] = "8th gen Core i3 (Cannon Lake)", | 384 | [0x66] = "8th gen Core i3 (Cannon Lake)", | |
386 | [0x6a] = "Future Xeon (Ice Lake)", | 385 | [0x6a] = "Future Xeon (Ice Lake)", | |
387 | [0x6c] = "Future Xeon (Ice Lake)", | 386 | [0x6c] = "Future Xeon (Ice Lake)", | |
388 | [0x7a] = "Atom (Goldmont Plus)", | 387 | [0x7a] = "Atom (Goldmont Plus)", | |
389 | [0x7d] = "10th gen Core (Ice Lake)", | 388 | [0x7d] = "10th gen Core (Ice Lake)", | |
390 | [0x7e] = "10th gen Core (Ice Lake)", | 389 | [0x7e] = "10th gen Core (Ice Lake)", | |
391 | [0x85] = "Xeon Phi 7215, 7285, 7295 (Knights Mill)", | 390 | [0x85] = "Xeon Phi 7215, 7285, 7295 (Knights Mill)", | |
392 | [0x86] = "Atom (Tremont)", | 391 | [0x86] = "Atom (Tremont)", | |
393 | [0x8e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)", | 392 | [0x8e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)", | |
394 | [0x9e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)", | 393 | [0x9e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)", | |
395 | }, | 394 | }, | |
396 | "Pentium Pro, II or III", /* Default */ | 395 | "Pentium Pro, II or III", /* Default */ | |
397 | NULL, | 396 | NULL, | |
398 | intel_family_new_probe, | 397 | intel_family_new_probe, | |
399 | intel_cpu_cacheinfo, | 398 | intel_cpu_cacheinfo, | |
400 | }, | 399 | }, | |
401 | /* Family > 6 */ | 400 | /* Family > 6 */ | |
402 | { | 401 | { | |
403 | CPUCLASS_686, | 402 | CPUCLASS_686, | |
404 | { | 403 | { | |
405 | 0, 0, 0, 0, 0, 0, 0, 0, | 404 | 0, 0, 0, 0, 0, 0, 0, 0, | |
406 | 0, 0, 0, 0, 0, 0, 0, 0, | 405 | 0, 0, 0, 0, 0, 0, 0, 0, | |
407 | }, | 406 | }, | |
408 | "Pentium 4", /* Default */ | 407 | "Pentium 4", /* Default */ | |
409 | NULL, | 408 | NULL, | |
410 | intel_family_new_probe, | 409 | intel_family_new_probe, | |
411 | intel_cpu_cacheinfo, | 410 | intel_cpu_cacheinfo, | |
412 | } } | 411 | } } | |
413 | }, | 412 | }, | |
414 | { | 413 | { | |
415 | "AuthenticAMD", | 414 | "AuthenticAMD", | |
416 | CPUVENDOR_AMD, | 415 | CPUVENDOR_AMD, | |
417 | "AMD", | 416 | "AMD", | |
418 | /* Family 4 */ | 417 | /* Family 4 */ | |
419 | { { | 418 | { { | |
420 | CPUCLASS_486, | 419 | CPUCLASS_486, | |
421 | { | 420 | { | |
422 | 0, 0, 0, "Am486DX2 W/T", | 421 | 0, 0, 0, "Am486DX2 W/T", | |
423 | 0, 0, 0, "Am486DX2 W/B", | 422 | 0, 0, 0, "Am486DX2 W/B", | |
424 | "Am486DX4 W/T or Am5x86 W/T 150", | 423 | "Am486DX4 W/T or Am5x86 W/T 150", | |
425 | "Am486DX4 W/B or Am5x86 W/B 150", 0, 0, | 424 | "Am486DX4 W/B or Am5x86 W/B 150", 0, 0, | |
426 | 0, 0, "Am5x86 W/T 133/160", | 425 | 0, 0, "Am5x86 W/T 133/160", | |
427 | "Am5x86 W/B 133/160", | 426 | "Am5x86 W/B 133/160", | |
428 | }, | 427 | }, | |
429 | "Am486 or Am5x86", /* Default */ | 428 | "Am486 or Am5x86", /* Default */ | |
430 | NULL, | 429 | NULL, | |
431 | NULL, | 430 | NULL, | |
432 | NULL, | 431 | NULL, | |
433 | }, | 432 | }, | |
434 | /* Family 5 */ | 433 | /* Family 5 */ | |
435 | { | 434 | { | |
436 | CPUCLASS_586, | 435 | CPUCLASS_586, | |
437 | { | 436 | { | |
438 | "K5", "K5", "K5", "K5", 0, 0, "K6", | 437 | "K5", "K5", "K5", "K5", 0, 0, "K6", | |
439 | "K6", "K6-2", "K6-III", "Geode LX", 0, 0, | 438 | "K6", "K6-2", "K6-III", "Geode LX", 0, 0, | |
440 | "K6-2+/III+", 0, 0, | 439 | "K6-2+/III+", 0, 0, | |
441 | }, | 440 | }, | |
442 | "K5 or K6", /* Default */ | 441 | "K5 or K6", /* Default */ | |
443 | amd_family5_setup, | 442 | amd_family5_setup, | |
444 | NULL, | 443 | NULL, | |
445 | amd_cpu_cacheinfo, | 444 | amd_cpu_cacheinfo, | |
446 | }, | 445 | }, | |
447 | /* Family 6 */ | 446 | /* Family 6 */ | |
448 | { | 447 | { | |
449 | CPUCLASS_686, | 448 | CPUCLASS_686, | |
450 | { | 449 | { | |
451 | 0, "Athlon Model 1", "Athlon Model 2", | 450 | 0, "Athlon Model 1", "Athlon Model 2", | |
452 | "Duron", "Athlon Model 4 (Thunderbird)", | 451 | "Duron", "Athlon Model 4 (Thunderbird)", | |
453 | 0, "Athlon", "Duron", "Athlon", 0, | 452 | 0, "Athlon", "Duron", "Athlon", 0, | |
454 | "Athlon", 0, 0, 0, 0, 0, | 453 | "Athlon", 0, 0, 0, 0, 0, | |
455 | }, | 454 | }, | |
456 | "K7 (Athlon)", /* Default */ | 455 | "K7 (Athlon)", /* Default */ | |
457 | NULL, | 456 | NULL, | |
458 | amd_family6_probe, | 457 | amd_family6_probe, | |
459 | amd_cpu_cacheinfo, | 458 | amd_cpu_cacheinfo, | |
460 | }, | 459 | }, | |
461 | /* Family > 6 */ | 460 | /* Family > 6 */ | |
462 | { | 461 | { | |
463 | CPUCLASS_686, | 462 | CPUCLASS_686, | |
464 | { | 463 | { | |
465 | 0, 0, 0, 0, 0, 0, 0, 0, | 464 | 0, 0, 0, 0, 0, 0, 0, 0, | |
466 | 0, 0, 0, 0, 0, 0, 0, 0, | 465 | 0, 0, 0, 0, 0, 0, 0, 0, | |
467 | }, | 466 | }, | |
468 | "Unknown K8 (Athlon)", /* Default */ | 467 | "Unknown K8 (Athlon)", /* Default */ | |
469 | NULL, | 468 | NULL, | |
470 | amd_family6_probe, | 469 | amd_family6_probe, | |
471 | amd_cpu_cacheinfo, | 470 | amd_cpu_cacheinfo, | |
472 | } } | 471 | } } | |
473 | }, | 472 | }, | |
474 | { | 473 | { | |
475 | "CyrixInstead", | 474 | "CyrixInstead", | |
476 | CPUVENDOR_CYRIX, | 475 | CPUVENDOR_CYRIX, | |
477 | "Cyrix", | 476 | "Cyrix", | |
478 | /* Family 4 */ | 477 | /* Family 4 */ | |
479 | { { | 478 | { { | |
480 | CPUCLASS_486, | 479 | CPUCLASS_486, | |
481 | { | 480 | { | |
482 | 0, 0, 0, | 481 | 0, 0, 0, | |
483 | "MediaGX", | 482 | "MediaGX", | |
484 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 483 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
485 | }, | 484 | }, | |
486 | "486", /* Default */ | 485 | "486", /* Default */ | |
487 | cyrix6x86_cpu_setup, /* XXX ?? */ | 486 | cyrix6x86_cpu_setup, /* XXX ?? */ | |
488 | NULL, | 487 | NULL, | |
489 | NULL, | 488 | NULL, | |
490 | }, | 489 | }, | |
491 | /* Family 5 */ | 490 | /* Family 5 */ | |
492 | { | 491 | { | |
493 | CPUCLASS_586, | 492 | CPUCLASS_586, | |
494 | { | 493 | { | |
495 | 0, 0, "6x86", 0, | 494 | 0, 0, "6x86", 0, | |
496 | "MMX-enhanced MediaGX (GXm)", /* or Geode? */ | 495 | "MMX-enhanced MediaGX (GXm)", /* or Geode? */ | |
497 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 496 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
498 | }, | 497 | }, | |
499 | "6x86", /* Default */ | 498 | "6x86", /* Default */ | |
500 | cyrix6x86_cpu_setup, | 499 | cyrix6x86_cpu_setup, | |
501 | NULL, | 500 | NULL, | |
502 | NULL, | 501 | NULL, | |
503 | }, | 502 | }, | |
504 | /* Family 6 */ | 503 | /* Family 6 */ | |
505 | { | 504 | { | |
506 | CPUCLASS_686, | 505 | CPUCLASS_686, | |
507 | { | 506 | { | |
508 | "6x86MX", 0, 0, 0, 0, 0, 0, 0, | 507 | "6x86MX", 0, 0, 0, 0, 0, 0, 0, | |
509 | 0, 0, 0, 0, 0, 0, 0, 0, | 508 | 0, 0, 0, 0, 0, 0, 0, 0, | |
510 | }, | 509 | }, | |
511 | "6x86MX", /* Default */ | 510 | "6x86MX", /* Default */ | |
512 | cyrix6x86_cpu_setup, | 511 | cyrix6x86_cpu_setup, | |
513 | NULL, | 512 | NULL, | |
514 | NULL, | 513 | NULL, | |
515 | }, | 514 | }, | |
516 | /* Family > 6 */ | 515 | /* Family > 6 */ | |
517 | { | 516 | { | |
518 | CPUCLASS_686, | 517 | CPUCLASS_686, | |
519 | { | 518 | { | |
520 | 0, 0, 0, 0, 0, 0, 0, 0, | 519 | 0, 0, 0, 0, 0, 0, 0, 0, | |
521 | 0, 0, 0, 0, 0, 0, 0, 0, | 520 | 0, 0, 0, 0, 0, 0, 0, 0, | |
522 | }, | 521 | }, | |
523 | "Unknown 6x86MX", /* Default */ | 522 | "Unknown 6x86MX", /* Default */ | |
524 | NULL, | 523 | NULL, | |
525 | NULL, | 524 | NULL, | |
526 | NULL, | 525 | NULL, | |
527 | } } | 526 | } } | |
528 | }, | 527 | }, | |
529 | { /* MediaGX is now owned by National Semiconductor */ | 528 | { /* MediaGX is now owned by National Semiconductor */ | |
530 | "Geode by NSC", | 529 | "Geode by NSC", | |
531 | CPUVENDOR_CYRIX, /* XXX */ | 530 | CPUVENDOR_CYRIX, /* XXX */ | |
532 | "National Semiconductor", | 531 | "National Semiconductor", | |
533 | /* Family 4, NSC never had any of these */ | 532 | /* Family 4, NSC never had any of these */ | |
534 | { { | 533 | { { | |
535 | CPUCLASS_486, | 534 | CPUCLASS_486, | |
536 | { | 535 | { | |
537 | 0, 0, 0, 0, 0, 0, 0, 0, | 536 | 0, 0, 0, 0, 0, 0, 0, 0, | |
538 | 0, 0, 0, 0, 0, 0, 0, 0, | 537 | 0, 0, 0, 0, 0, 0, 0, 0, | |
539 | }, | 538 | }, | |
540 | "486 compatible", /* Default */ | 539 | "486 compatible", /* Default */ | |
541 | NULL, | 540 | NULL, | |
542 | NULL, | 541 | NULL, | |
543 | NULL, | 542 | NULL, | |
544 | }, | 543 | }, | |
545 | /* Family 5: Geode family, formerly MediaGX */ | 544 | /* Family 5: Geode family, formerly MediaGX */ | |
546 | { | 545 | { | |
547 | CPUCLASS_586, | 546 | CPUCLASS_586, | |
548 | { | 547 | { | |
549 | 0, 0, 0, 0, | 548 | 0, 0, 0, 0, | |
550 | "Geode GX1", | 549 | "Geode GX1", | |
551 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 550 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
552 | }, | 551 | }, | |
553 | "Geode", /* Default */ | 552 | "Geode", /* Default */ | |
554 | cyrix6x86_cpu_setup, | 553 | cyrix6x86_cpu_setup, | |
555 | NULL, | 554 | NULL, | |
556 | amd_cpu_cacheinfo, | 555 | amd_cpu_cacheinfo, | |
557 | }, | 556 | }, | |
558 | /* Family 6, not yet available from NSC */ | 557 | /* Family 6, not yet available from NSC */ | |
559 | { | 558 | { | |
560 | CPUCLASS_686, | 559 | CPUCLASS_686, | |
561 | { | 560 | { | |
562 | 0, 0, 0, 0, 0, 0, 0, 0, | 561 | 0, 0, 0, 0, 0, 0, 0, 0, | |
563 | 0, 0, 0, 0, 0, 0, 0, 0, | 562 | 0, 0, 0, 0, 0, 0, 0, 0, | |
564 | }, | 563 | }, | |
565 | "Pentium Pro compatible", /* Default */ | 564 | "Pentium Pro compatible", /* Default */ | |
566 | NULL, | 565 | NULL, | |
567 | NULL, | 566 | NULL, | |
568 | NULL, | 567 | NULL, | |
569 | }, | 568 | }, | |
570 | /* Family > 6, not yet available from NSC */ | 569 | /* Family > 6, not yet available from NSC */ | |
571 | { | 570 | { | |
572 | CPUCLASS_686, | 571 | CPUCLASS_686, | |
573 | { | 572 | { | |
574 | 0, 0, 0, 0, 0, 0, 0, 0, | 573 | 0, 0, 0, 0, 0, 0, 0, 0, | |
575 | 0, 0, 0, 0, 0, 0, 0, 0, | 574 | 0, 0, 0, 0, 0, 0, 0, 0, | |
576 | }, | 575 | }, | |
577 | "Pentium Pro compatible", /* Default */ | 576 | "Pentium Pro compatible", /* Default */ | |
578 | NULL, | 577 | NULL, | |
579 | NULL, | 578 | NULL, | |
580 | NULL, | 579 | NULL, | |
581 | } } | 580 | } } | |
582 | }, | 581 | }, | |
583 | { | 582 | { | |
584 | "CentaurHauls", | 583 | "CentaurHauls", | |
585 | CPUVENDOR_IDT, | 584 | CPUVENDOR_IDT, | |
586 | "IDT", | 585 | "IDT", | |
587 | /* Family 4, IDT never had any of these */ | 586 | /* Family 4, IDT never had any of these */ | |
588 | { { | 587 | { { | |
589 | CPUCLASS_486, | 588 | CPUCLASS_486, | |
590 | { | 589 | { | |
591 | 0, 0, 0, 0, 0, 0, 0, 0, | 590 | 0, 0, 0, 0, 0, 0, 0, 0, | |
592 | 0, 0, 0, 0, 0, 0, 0, 0, | 591 | 0, 0, 0, 0, 0, 0, 0, 0, | |
593 | }, | 592 | }, | |
594 | "486 compatible", /* Default */ | 593 | "486 compatible", /* Default */ | |
595 | NULL, | 594 | NULL, | |
596 | NULL, | 595 | NULL, | |
597 | NULL, | 596 | NULL, | |
598 | }, | 597 | }, | |
599 | /* Family 5 */ | 598 | /* Family 5 */ | |
600 | { | 599 | { | |
601 | CPUCLASS_586, | 600 | CPUCLASS_586, | |
602 | { | 601 | { | |
603 | 0, 0, 0, 0, "WinChip C6", 0, 0, 0, | 602 | 0, 0, 0, 0, "WinChip C6", 0, 0, 0, | |
604 | "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0, | 603 | "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0, | |
605 | }, | 604 | }, | |
606 | "WinChip", /* Default */ | 605 | "WinChip", /* Default */ | |
607 | winchip_cpu_setup, | 606 | winchip_cpu_setup, | |
608 | NULL, | 607 | NULL, | |
609 | NULL, | 608 | NULL, | |
610 | }, | 609 | }, | |
611 | /* Family 6, VIA acquired IDT Centaur design subsidiary */ | 610 | /* Family 6, VIA acquired IDT Centaur design subsidiary */ | |
612 | { | 611 | { | |
613 | CPUCLASS_686, | 612 | CPUCLASS_686, | |
614 | { | 613 | { | |
615 | 0, 0, 0, 0, 0, 0, "C3 Samuel", | 614 | 0, 0, 0, 0, 0, 0, "C3 Samuel", | |
616 | "C3 Samuel 2/Ezra", "C3 Ezra-T", | 615 | "C3 Samuel 2/Ezra", "C3 Ezra-T", | |
617 | "C3 Nehemiah", "C7 Esther", 0, 0, "C7 Esther", | 616 | "C3 Nehemiah", "C7 Esther", 0, 0, "C7 Esther", | |
618 | 0, "VIA Nano", | 617 | 0, "VIA Nano", | |
619 | }, | 618 | }, | |
620 | "Unknown VIA/IDT", /* Default */ | 619 | "Unknown VIA/IDT", /* Default */ | |
621 | NULL, | 620 | NULL, | |
622 | via_cpu_probe, | 621 | via_cpu_probe, | |
623 | via_cpu_cacheinfo, | 622 | via_cpu_cacheinfo, | |
624 | }, | 623 | }, | |
625 | /* Family > 6, not yet available from VIA */ | 624 | /* Family > 6, not yet available from VIA */ | |
626 | { | 625 | { | |
627 | CPUCLASS_686, | 626 | CPUCLASS_686, | |
628 | { | 627 | { | |
629 | 0, 0, 0, 0, 0, 0, 0, 0, | 628 | 0, 0, 0, 0, 0, 0, 0, 0, | |
630 | 0, 0, 0, 0, 0, 0, 0, 0, | 629 | 0, 0, 0, 0, 0, 0, 0, 0, | |
631 | }, | 630 | }, | |
632 | "Pentium Pro compatible", /* Default */ | 631 | "Pentium Pro compatible", /* Default */ | |
633 | NULL, | 632 | NULL, | |
634 | NULL, | 633 | NULL, | |
635 | NULL, | 634 | NULL, | |
636 | } } | 635 | } } | |
637 | }, | 636 | }, | |
638 | { | 637 | { | |
639 | "GenuineTMx86", | 638 | "GenuineTMx86", | |
640 | CPUVENDOR_TRANSMETA, | 639 | CPUVENDOR_TRANSMETA, | |
641 | "Transmeta", | 640 | "Transmeta", | |
642 | /* Family 4, Transmeta never had any of these */ | 641 | /* Family 4, Transmeta never had any of these */ | |
643 | { { | 642 | { { | |
644 | CPUCLASS_486, | 643 | CPUCLASS_486, | |
645 | { | 644 | { | |
646 | 0, 0, 0, 0, 0, 0, 0, 0, | 645 | 0, 0, 0, 0, 0, 0, 0, 0, | |
647 | 0, 0, 0, 0, 0, 0, 0, 0, | 646 | 0, 0, 0, 0, 0, 0, 0, 0, | |
648 | }, | 647 | }, | |
649 | "486 compatible", /* Default */ | 648 | "486 compatible", /* Default */ | |
650 | NULL, | 649 | NULL, | |
651 | NULL, | 650 | NULL, | |
652 | NULL, | 651 | NULL, | |
653 | }, | 652 | }, | |
654 | /* Family 5 */ | 653 | /* Family 5 */ | |
655 | { | 654 | { | |
656 | CPUCLASS_586, | 655 | CPUCLASS_586, | |
657 | { | 656 | { | |
658 | 0, 0, 0, 0, 0, 0, 0, 0, | 657 | 0, 0, 0, 0, 0, 0, 0, 0, | |
659 | 0, 0, 0, 0, 0, 0, 0, 0, | 658 | 0, 0, 0, 0, 0, 0, 0, 0, | |
660 | }, | 659 | }, | |
661 | "Crusoe", /* Default */ | 660 | "Crusoe", /* Default */ | |
662 | NULL, | 661 | NULL, | |
663 | NULL, | 662 | NULL, | |
664 | transmeta_cpu_info, | 663 | transmeta_cpu_info, | |
665 | }, | 664 | }, | |
666 | /* Family 6, not yet available from Transmeta */ | 665 | /* Family 6, not yet available from Transmeta */ | |
667 | { | 666 | { | |
668 | CPUCLASS_686, | 667 | CPUCLASS_686, | |
669 | { | 668 | { | |
670 | 0, 0, 0, 0, 0, 0, 0, 0, | 669 | 0, 0, 0, 0, 0, 0, 0, 0, | |
671 | 0, 0, 0, 0, 0, 0, 0, 0, | 670 | 0, 0, 0, 0, 0, 0, 0, 0, | |
672 | }, | 671 | }, | |
673 | "Pentium Pro compatible", /* Default */ | 672 | "Pentium Pro compatible", /* Default */ | |
674 | NULL, | 673 | NULL, | |
675 | NULL, | 674 | NULL, | |
676 | NULL, | 675 | NULL, | |
677 | }, | 676 | }, | |
678 | /* Family > 6, not yet available from Transmeta */ | 677 | /* Family > 6, not yet available from Transmeta */ | |
679 | { | 678 | { | |
680 | CPUCLASS_686, | 679 | CPUCLASS_686, | |
681 | { | 680 | { | |
682 | 0, 0, 0, 0, 0, 0, 0, 0, | 681 | 0, 0, 0, 0, 0, 0, 0, 0, | |
683 | 0, 0, 0, 0, 0, 0, 0, 0, | 682 | 0, 0, 0, 0, 0, 0, 0, 0, | |
684 | }, | 683 | }, | |
685 | "Pentium Pro compatible", /* Default */ | 684 | "Pentium Pro compatible", /* Default */ | |
686 | NULL, | 685 | NULL, | |
687 | NULL, | 686 | NULL, | |
688 | NULL, | 687 | NULL, | |
689 | } } | 688 | } } | |
690 | } | 689 | } | |
691 | }; | 690 | }; | |
692 | 691 | |||
693 | /* | 692 | /* | |
694 | * disable the TSC such that we don't use the TSC in microtime(9) | 693 | * disable the TSC such that we don't use the TSC in microtime(9) | |
695 | * because some CPUs got the implementation wrong. | 694 | * because some CPUs got the implementation wrong. | |
696 | */ | 695 | */ | |
697 | static void | 696 | static void | |
698 | disable_tsc(struct cpu_info *ci) | 697 | disable_tsc(struct cpu_info *ci) | |
699 | { | 698 | { | |
700 | if (ci->ci_feat_val[0] & CPUID_TSC) { | 699 | if (ci->ci_feat_val[0] & CPUID_TSC) { | |
701 | ci->ci_feat_val[0] &= ~CPUID_TSC; | 700 | ci->ci_feat_val[0] &= ~CPUID_TSC; | |
702 | aprint_error("WARNING: broken TSC disabled\n"); | 701 | aprint_error("WARNING: broken TSC disabled\n"); | |
703 | } | 702 | } | |
704 | } | 703 | } | |
705 | 704 | |||
706 | static void | 705 | static void | |
707 | amd_family5_setup(struct cpu_info *ci) | 706 | amd_family5_setup(struct cpu_info *ci) | |
708 | { | 707 | { | |
709 | 708 | |||
710 | switch (ci->ci_model) { | 709 | switch (ci->ci_model) { | |
711 | case 0: /* AMD-K5 Model 0 */ | 710 | case 0: /* AMD-K5 Model 0 */ | |
712 | /* | 711 | /* | |
713 | * According to the AMD Processor Recognition App Note, | 712 | * According to the AMD Processor Recognition App Note, | |
714 | * the AMD-K5 Model 0 uses the wrong bit to indicate | 713 | * the AMD-K5 Model 0 uses the wrong bit to indicate | |
715 | * support for global PTEs, instead using bit 9 (APIC) | 714 | * support for global PTEs, instead using bit 9 (APIC) | |
716 | * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). | 715 | * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). | |
717 | */ | 716 | */ | |
718 | if (ci->ci_feat_val[0] & CPUID_APIC) | 717 | if (ci->ci_feat_val[0] & CPUID_APIC) | |
719 | ci->ci_feat_val[0] = | 718 | ci->ci_feat_val[0] = | |
720 | (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE; | 719 | (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE; | |
721 | /* | 720 | /* | |
722 | * XXX But pmap_pg_g is already initialized -- need to kick | 721 | * XXX But pmap_pg_g is already initialized -- need to kick | |
723 | * XXX the pmap somehow. How does the MP branch do this? | 722 | * XXX the pmap somehow. How does the MP branch do this? | |
724 | */ | 723 | */ | |
725 | break; | 724 | break; | |
726 | } | 725 | } | |
727 | } | 726 | } | |
728 | 727 | |||
729 | static void | 728 | static void | |
730 | cyrix6x86_cpu_setup(struct cpu_info *ci) | 729 | cyrix6x86_cpu_setup(struct cpu_info *ci) | |
731 | { | 730 | { | |
732 | 731 | |||
733 | /* | 732 | /* | |
734 | * Do not disable the TSC on the Geode GX, it's reported to | 733 | * Do not disable the TSC on the Geode GX, it's reported to | |
735 | * work fine. | 734 | * work fine. | |
736 | */ | 735 | */ | |
737 | if (ci->ci_signature != 0x552) | 736 | if (ci->ci_signature != 0x552) | |
738 | disable_tsc(ci); | 737 | disable_tsc(ci); | |
739 | } | 738 | } | |
740 | 739 | |||
741 | static void | 740 | static void | |
742 | winchip_cpu_setup(struct cpu_info *ci) | 741 | winchip_cpu_setup(struct cpu_info *ci) | |
743 | { | 742 | { | |
744 | switch (ci->ci_model) { | 743 | switch (ci->ci_model) { | |
745 | case 4: /* WinChip C6 */ | 744 | case 4: /* WinChip C6 */ | |
746 | disable_tsc(ci); | 745 | disable_tsc(ci); | |
747 | } | 746 | } | |
748 | } | 747 | } | |
749 | 748 | |||
750 | 749 | |||
751 | static const char * | 750 | static const char * | |
752 | intel_family6_name(struct cpu_info *ci) | 751 | intel_family6_name(struct cpu_info *ci) | |
753 | { | 752 | { | |
754 | const char *ret = NULL; | 753 | const char *ret = NULL; | |
755 | u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize; | 754 | u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize; | |
756 | 755 | |||
757 | if (ci->ci_model == 5) { | 756 | if (ci->ci_model == 5) { | |
758 | switch (l2cache) { | 757 | switch (l2cache) { | |
759 | case 0: | 758 | case 0: | |
760 | case 128 * 1024: | 759 | case 128 * 1024: | |
761 | ret = "Celeron (Covington)"; | 760 | ret = "Celeron (Covington)"; | |
762 | break; | 761 | break; | |
763 | case 256 * 1024: | 762 | case 256 * 1024: | |
764 | ret = "Mobile Pentium II (Dixon)"; | 763 | ret = "Mobile Pentium II (Dixon)"; | |
765 | break; | 764 | break; | |
766 | case 512 * 1024: | 765 | case 512 * 1024: | |
767 | ret = "Pentium II"; | 766 | ret = "Pentium II"; | |
768 | break; | 767 | break; | |
769 | case 1 * 1024 * 1024: | 768 | case 1 * 1024 * 1024: | |
770 | case 2 * 1024 * 1024: | 769 | case 2 * 1024 * 1024: | |
771 | ret = "Pentium II Xeon"; | 770 | ret = "Pentium II Xeon"; | |
772 | break; | 771 | break; | |
773 | } | 772 | } | |
774 | } else if (ci->ci_model == 6) { | 773 | } else if (ci->ci_model == 6) { | |
775 | switch (l2cache) { | 774 | switch (l2cache) { | |
776 | case 256 * 1024: | 775 | case 256 * 1024: | |
777 | case 512 * 1024: | 776 | case 512 * 1024: | |
778 | ret = "Mobile Pentium II"; | 777 | ret = "Mobile Pentium II"; | |
779 | break; | 778 | break; | |
780 | } | 779 | } | |
781 | } else if (ci->ci_model == 7) { | 780 | } else if (ci->ci_model == 7) { | |
782 | switch (l2cache) { | 781 | switch (l2cache) { | |
783 | case 512 * 1024: | 782 | case 512 * 1024: | |
784 | ret = "Pentium III"; | 783 | ret = "Pentium III"; | |
785 | break; | 784 | break; | |
786 | case 1 * 1024 * 1024: | 785 | case 1 * 1024 * 1024: | |
787 | case 2 * 1024 * 1024: | 786 | case 2 * 1024 * 1024: | |
788 | ret = "Pentium III Xeon"; | 787 | ret = "Pentium III Xeon"; | |
789 | break; | 788 | break; | |
790 | } | 789 | } | |
791 | } else if (ci->ci_model >= 8) { | 790 | } else if (ci->ci_model >= 8) { | |
792 | if (ci->ci_brand_id && ci->ci_brand_id < 0x10) { | 791 | if (ci->ci_brand_id && ci->ci_brand_id < 0x10) { | |
793 | switch (ci->ci_brand_id) { | 792 | switch (ci->ci_brand_id) { | |
794 | case 0x3: | 793 | case 0x3: | |
795 | if (ci->ci_signature == 0x6B1) | 794 | if (ci->ci_signature == 0x6B1) | |
796 | ret = "Celeron"; | 795 | ret = "Celeron"; | |
797 | break; | 796 | break; | |
798 | case 0x8: | 797 | case 0x8: | |
799 | if (ci->ci_signature >= 0xF13) | 798 | if (ci->ci_signature >= 0xF13) | |
800 | ret = "genuine processor"; | 799 | ret = "genuine processor"; | |
801 | break; | 800 | break; | |
802 | case 0xB: | 801 | case 0xB: | |
803 | if (ci->ci_signature >= 0xF13) | 802 | if (ci->ci_signature >= 0xF13) | |
804 | ret = "Xeon MP"; | 803 | ret = "Xeon MP"; | |
805 | break; | 804 | break; | |
806 | case 0xE: | 805 | case 0xE: | |
807 | if (ci->ci_signature < 0xF13) | 806 | if (ci->ci_signature < 0xF13) | |
808 | ret = "Xeon"; | 807 | ret = "Xeon"; | |
809 | break; | 808 | break; | |
810 | } | 809 | } | |
811 | if (ret == NULL) | 810 | if (ret == NULL) | |
812 | ret = i386_intel_brand[ci->ci_brand_id]; | 811 | ret = i386_intel_brand[ci->ci_brand_id]; | |
813 | } | 812 | } | |
814 | } | 813 | } | |
815 | 814 | |||
816 | return ret; | 815 | return ret; | |
817 | } | 816 | } | |
818 | 817 | |||
819 | /* | 818 | /* | |
820 | * Identify AMD64 CPU names from cpuid. | 819 | * Identify AMD64 CPU names from cpuid. | |
821 | * | 820 | * | |
822 | * Based on: | 821 | * Based on: | |
823 | * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" | 822 | * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" | |
824 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf | 823 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf | |
825 | * "Revision Guide for AMD NPT Family 0Fh Processors" | 824 | * "Revision Guide for AMD NPT Family 0Fh Processors" | |
826 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf | 825 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf | |
827 | * and other miscellaneous reports. | 826 | * and other miscellaneous reports. | |
828 | * | 827 | * | |
829 | * This is all rather pointless, these are cross 'brand' since the raw | 828 | * This is all rather pointless, these are cross 'brand' since the raw | |
830 | * silicon is shared. | 829 | * silicon is shared. | |
831 | */ | 830 | */ | |
832 | static const char * | 831 | static const char * | |
833 | amd_amd64_name(struct cpu_info *ci) | 832 | amd_amd64_name(struct cpu_info *ci) | |
834 | { | 833 | { | |
835 | static char family_str[32]; | 834 | static char family_str[32]; | |
836 | 835 | |||
837 | /* Only called if family >= 15 */ | 836 | /* Only called if family >= 15 */ | |
838 | 837 | |||
839 | switch (ci->ci_family) { | 838 | switch (ci->ci_family) { | |
840 | case 15: | 839 | case 15: | |
841 | switch (ci->ci_model) { | 840 | switch (ci->ci_model) { | |
842 | case 0x21: /* rev JH-E1/E6 */ | 841 | case 0x21: /* rev JH-E1/E6 */ | |
843 | case 0x41: /* rev JH-F2 */ | 842 | case 0x41: /* rev JH-F2 */ | |
844 | return "Dual-Core Opteron"; | 843 | return "Dual-Core Opteron"; | |
845 | case 0x23: /* rev JH-E6 (Toledo) */ | 844 | case 0x23: /* rev JH-E6 (Toledo) */ | |
846 | return "Dual-Core Opteron or Athlon 64 X2"; | 845 | return "Dual-Core Opteron or Athlon 64 X2"; | |
847 | case 0x43: /* rev JH-F2 (Windsor) */ | 846 | case 0x43: /* rev JH-F2 (Windsor) */ | |
848 | return "Athlon 64 FX or Athlon 64 X2"; | 847 | return "Athlon 64 FX or Athlon 64 X2"; | |
849 | case 0x24: /* rev SH-E5 (Lancaster?) */ | 848 | case 0x24: /* rev SH-E5 (Lancaster?) */ | |
850 | return "Mobile Athlon 64 or Turion 64"; | 849 | return "Mobile Athlon 64 or Turion 64"; | |
851 | case 0x05: /* rev SH-B0/B3/C0/CG (SledgeHammer?) */ | 850 | case 0x05: /* rev SH-B0/B3/C0/CG (SledgeHammer?) */ | |
852 | return "Opteron or Athlon 64 FX"; | 851 | return "Opteron or Athlon 64 FX"; | |
853 | case 0x15: /* rev SH-D0 */ | 852 | case 0x15: /* rev SH-D0 */ | |
854 | case 0x25: /* rev SH-E4 */ | 853 | case 0x25: /* rev SH-E4 */ | |
855 | return "Opteron"; | 854 | return "Opteron"; | |
856 | case 0x27: /* rev DH-E4, SH-E4 */ | 855 | case 0x27: /* rev DH-E4, SH-E4 */ | |
857 | return "Athlon 64 or Athlon 64 FX or Opteron"; | 856 | return "Athlon 64 or Athlon 64 FX or Opteron"; | |
858 | case 0x48: /* rev BH-F2 */ | 857 | case 0x48: /* rev BH-F2 */ | |
859 | return "Turion 64 X2"; | 858 | return "Turion 64 X2"; | |
860 | case 0x04: /* rev SH-B0/C0/CG (ClawHammer) */ | 859 | case 0x04: /* rev SH-B0/C0/CG (ClawHammer) */ | |
861 | case 0x07: /* rev SH-CG (ClawHammer) */ | 860 | case 0x07: /* rev SH-CG (ClawHammer) */ | |
862 | case 0x0b: /* rev CH-CG */ | 861 | case 0x0b: /* rev CH-CG */ | |
863 | case 0x14: /* rev SH-D0 */ | 862 | case 0x14: /* rev SH-D0 */ | |
864 | case 0x17: /* rev SH-D0 */ | 863 | case 0x17: /* rev SH-D0 */ | |
865 | case 0x1b: /* rev CH-D0 */ | 864 | case 0x1b: /* rev CH-D0 */ | |
866 | return "Athlon 64"; | 865 | return "Athlon 64"; | |
867 | case 0x2b: /* rev BH-E4 (Manchester) */ | 866 | case 0x2b: /* rev BH-E4 (Manchester) */ | |
868 | case 0x4b: /* rev BH-F2 (Windsor) */ | 867 | case 0x4b: /* rev BH-F2 (Windsor) */ | |
869 | return "Athlon 64 X2"; | 868 | return "Athlon 64 X2"; | |
870 | case 0x6b: /* rev BH-G1 (Brisbane) */ | 869 | case 0x6b: /* rev BH-G1 (Brisbane) */ | |
871 | return "Athlon X2 or Athlon 64 X2"; | 870 | return "Athlon X2 or Athlon 64 X2"; | |
872 | case 0x08: /* rev CH-CG */ | 871 | case 0x08: /* rev CH-CG */ | |
873 | case 0x0c: /* rev DH-CG (Newcastle) */ | 872 | case 0x0c: /* rev DH-CG (Newcastle) */ | |
874 | case 0x0e: /* rev DH-CG (Newcastle?) */ | 873 | case 0x0e: /* rev DH-CG (Newcastle?) */ | |
875 | case 0x0f: /* rev DH-CG (Newcastle/Paris) */ | 874 | case 0x0f: /* rev DH-CG (Newcastle/Paris) */ | |
876 | case 0x18: /* rev CH-D0 */ | 875 | case 0x18: /* rev CH-D0 */ | |
877 | case 0x1c: /* rev DH-D0 (Winchester) */ | 876 | case 0x1c: /* rev DH-D0 (Winchester) */ | |
878 | case 0x1f: /* rev DH-D0 (Winchester/Victoria) */ | 877 | case 0x1f: /* rev DH-D0 (Winchester/Victoria) */ | |
879 | case 0x2c: /* rev DH-E3/E6 */ | 878 | case 0x2c: /* rev DH-E3/E6 */ | |
880 | case 0x2f: /* rev DH-E3/E6 (Venice/Palermo) */ | 879 | case 0x2f: /* rev DH-E3/E6 (Venice/Palermo) */ | |
881 | case 0x4f: /* rev DH-F2 (Orleans/Manila) */ | 880 | case 0x4f: /* rev DH-F2 (Orleans/Manila) */ | |
882 | case 0x5f: /* rev DH-F2 (Orleans/Manila) */ | 881 | case 0x5f: /* rev DH-F2 (Orleans/Manila) */ | |
883 | case 0x6f: /* rev DH-G1 */ | 882 | case 0x6f: /* rev DH-G1 */ | |
884 | return "Athlon 64 or Sempron"; | 883 | return "Athlon 64 or Sempron"; | |
885 | default: | 884 | default: | |
886 | break; | 885 | break; | |
887 | } | 886 | } | |
888 | return "Unknown AMD64 CPU"; | 887 | return "Unknown AMD64 CPU"; | |
889 | 888 | |||
890 | #if 0 | 889 | #if 0 | |
891 | case 16: | 890 | case 16: | |
892 | return "Family 10h"; | 891 | return "Family 10h"; | |
893 | case 17: | 892 | case 17: | |
894 | return "Family 11h"; | 893 | return "Family 11h"; | |
895 | case 18: | 894 | case 18: | |
896 | return "Family 12h"; | 895 | return "Family 12h"; | |
897 | case 19: | 896 | case 19: | |
898 | return "Family 14h"; | 897 | return "Family 14h"; | |
899 | case 20: | 898 | case 20: | |
900 | return "Family 15h"; | 899 | return "Family 15h"; | |
901 | #endif | 900 | #endif | |
902 | 901 | |||
903 | default: | 902 | default: | |
904 | break; | 903 | break; | |
905 | } | 904 | } | |
906 | 905 | |||
907 | snprintf(family_str, sizeof family_str, "Family %xh", ci->ci_family); | 906 | snprintf(family_str, sizeof family_str, "Family %xh", ci->ci_family); | |
908 | return family_str; | 907 | return family_str; | |
909 | } | 908 | } | |
910 | 909 | |||
911 | static void | 910 | static void | |
912 | intel_family_new_probe(struct cpu_info *ci) | 911 | intel_family_new_probe(struct cpu_info *ci) | |
913 | { | 912 | { | |
914 | uint32_t descs[4]; | 913 | uint32_t descs[4]; | |
915 | 914 | |||
916 | x86_cpuid(0x80000000, descs); | 915 | x86_cpuid(0x80000000, descs); | |
917 | 916 | |||
918 | /* | 917 | /* | |
919 | * Determine extended feature flags. | 918 | * Determine extended feature flags. | |
920 | */ | 919 | */ | |
921 | if (descs[0] >= 0x80000001) { | 920 | if (descs[0] >= 0x80000001) { | |
922 | x86_cpuid(0x80000001, descs); | 921 | x86_cpuid(0x80000001, descs); | |
923 | ci->ci_feat_val[2] |= descs[3]; | 922 | ci->ci_feat_val[2] |= descs[3]; | |
924 | ci->ci_feat_val[3] |= descs[2]; | 923 | ci->ci_feat_val[3] |= descs[2]; | |
925 | } | 924 | } | |
926 | } | 925 | } | |
927 | 926 | |||
928 | static void | 927 | static void | |
929 | via_cpu_probe(struct cpu_info *ci) | 928 | via_cpu_probe(struct cpu_info *ci) | |
930 | { | 929 | { | |
931 | u_int stepping = CPUID_TO_STEPPING(ci->ci_signature); | 930 | u_int stepping = CPUID_TO_STEPPING(ci->ci_signature); | |
932 | u_int descs[4]; | 931 | u_int descs[4]; | |
933 | u_int lfunc; | 932 | u_int lfunc; | |
934 | 933 | |||
935 | /* | 934 | /* | |
936 | * Determine the largest extended function value. | 935 | * Determine the largest extended function value. | |
937 | */ | 936 | */ | |
938 | x86_cpuid(0x80000000, descs); | 937 | x86_cpuid(0x80000000, descs); | |
939 | lfunc = descs[0]; | 938 | lfunc = descs[0]; | |
940 | 939 | |||
941 | /* | 940 | /* | |
942 | * Determine the extended feature flags. | 941 | * Determine the extended feature flags. | |
943 | */ | 942 | */ | |
944 | if (lfunc >= 0x80000001) { | 943 | if (lfunc >= 0x80000001) { | |
945 | x86_cpuid(0x80000001, descs); | 944 | x86_cpuid(0x80000001, descs); | |
946 | ci->ci_feat_val[2] |= descs[3]; | 945 | ci->ci_feat_val[2] |= descs[3]; | |
947 | } | 946 | } | |
948 | 947 | |||
949 | if (ci->ci_model < 0x9 || (ci->ci_model == 0x9 && stepping < 3)) | 948 | if (ci->ci_model < 0x9 || (ci->ci_model == 0x9 && stepping < 3)) | |
950 | return; | 949 | return; | |
951 | 950 | |||
952 | /* Nehemiah or Esther */ | 951 | /* Nehemiah or Esther */ | |
953 | x86_cpuid(0xc0000000, descs); | 952 | x86_cpuid(0xc0000000, descs); | |
954 | lfunc = descs[0]; | 953 | lfunc = descs[0]; | |
955 | if (lfunc < 0xc0000001) /* no ACE, no RNG */ | 954 | if (lfunc < 0xc0000001) /* no ACE, no RNG */ | |
956 | return; | 955 | return; | |
957 | 956 | |||
958 | x86_cpuid(0xc0000001, descs); | 957 | x86_cpuid(0xc0000001, descs); | |
959 | lfunc = descs[3]; | 958 | lfunc = descs[3]; | |
960 | ci->ci_feat_val[4] = lfunc; | 959 | ci->ci_feat_val[4] = lfunc; | |
961 | } | 960 | } | |
962 | 961 | |||
963 | static void | 962 | static void | |
964 | amd_family6_probe(struct cpu_info *ci) | 963 | amd_family6_probe(struct cpu_info *ci) | |
965 | { | 964 | { | |
966 | uint32_t descs[4]; | 965 | uint32_t descs[4]; | |
967 | char *p; | 966 | char *p; | |
968 | size_t i; | 967 | size_t i; | |
969 | 968 | |||
970 | x86_cpuid(0x80000000, descs); | 969 | x86_cpuid(0x80000000, descs); | |
971 | 970 | |||
972 | /* | 971 | /* | |
973 | * Determine the extended feature flags. | 972 | * Determine the extended feature flags. | |
974 | */ | 973 | */ | |
975 | if (descs[0] >= 0x80000001) { | 974 | if (descs[0] >= 0x80000001) { | |
976 | x86_cpuid(0x80000001, descs); | 975 | x86_cpuid(0x80000001, descs); | |
977 | ci->ci_feat_val[2] |= descs[3]; /* %edx */ | 976 | ci->ci_feat_val[2] |= descs[3]; /* %edx */ | |
978 | ci->ci_feat_val[3] = descs[2]; /* %ecx */ | 977 | ci->ci_feat_val[3] = descs[2]; /* %ecx */ | |
979 | } | 978 | } | |
980 | 979 | |||
981 | if (*cpu_brand_string == '\0') | 980 | if (*cpu_brand_string == '\0') | |
982 | return; | 981 | return; | |
983 | 982 | |||
984 | for (i = 1; i < __arraycount(amd_brand); i++) | 983 | for (i = 1; i < __arraycount(amd_brand); i++) | |
985 | if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) { | 984 | if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) { | |
986 | ci->ci_brand_id = i; | 985 | ci->ci_brand_id = i; | |
987 | strlcpy(amd_brand_name, p, sizeof(amd_brand_name)); | 986 | strlcpy(amd_brand_name, p, sizeof(amd_brand_name)); | |
988 | break; | 987 | break; | |
989 | } | 988 | } | |
990 | } | 989 | } | |
991 | 990 | |||
992 | /* | 991 | /* | |
993 | * Get cache info from one of the following: | 992 | * Get cache info from one of the following: | |
994 | * Intel Deterministic Cache Parameter Leaf (0x04) | 993 | * Intel Deterministic Cache Parameter Leaf (0x04) | |
995 | * AMD Cache Topology Information Leaf (0x8000001d) | 994 | * AMD Cache Topology Information Leaf (0x8000001d) | |
996 | */ | 995 | */ | |
997 | static void | 996 | static void | |
998 | cpu_dcp_cacheinfo(struct cpu_info *ci, uint32_t leaf) | 997 | cpu_dcp_cacheinfo(struct cpu_info *ci, uint32_t leaf) | |
999 | { | 998 | { | |
1000 | u_int descs[4]; | 999 | u_int descs[4]; | |
1001 | int type, level, ways, partitions, linesize, sets, totalsize; | 1000 | int type, level, ways, partitions, linesize, sets, totalsize; | |
1002 | int caitype = -1; | 1001 | int caitype = -1; | |
1003 | int i; | 1002 | int i; | |
1004 | 1003 | |||
1005 | for (i = 0; ; i++) { | 1004 | for (i = 0; ; i++) { | |
1006 | x86_cpuid2(leaf, i, descs); | 1005 | x86_cpuid2(leaf, i, descs); | |
1007 | type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE); | 1006 | type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE); | |
1008 | if (type == CPUID_DCP_CACHETYPE_N) | 1007 | if (type == CPUID_DCP_CACHETYPE_N) | |
1009 | break; | 1008 | break; | |
1010 | level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL); | 1009 | level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL); | |
1011 | switch (level) { | 1010 | switch (level) { | |
1012 | case 1: | 1011 | case 1: | |
1013 | if (type == CPUID_DCP_CACHETYPE_I) | 1012 | if (type == CPUID_DCP_CACHETYPE_I) | |
1014 | caitype = CAI_ICACHE; | 1013 | caitype = CAI_ICACHE; | |
1015 | else if (type == CPUID_DCP_CACHETYPE_D) | 1014 | else if (type == CPUID_DCP_CACHETYPE_D) | |
1016 | caitype = CAI_DCACHE; | 1015 | caitype = CAI_DCACHE; | |
1017 | else | 1016 | else | |
1018 | caitype = -1; | 1017 | caitype = -1; | |
1019 | break; | 1018 | break; | |
1020 | case 2: | 1019 | case 2: | |
1021 | if (type == CPUID_DCP_CACHETYPE_U) | 1020 | if (type == CPUID_DCP_CACHETYPE_U) | |
1022 | caitype = CAI_L2CACHE; | 1021 | caitype = CAI_L2CACHE; | |
1023 | else | 1022 | else | |
1024 | caitype = -1; | 1023 | caitype = -1; | |
1025 | break; | 1024 | break; | |
1026 | case 3: | 1025 | case 3: | |
1027 | if (type == CPUID_DCP_CACHETYPE_U) | 1026 | if (type == CPUID_DCP_CACHETYPE_U) | |
1028 | caitype = CAI_L3CACHE; | 1027 | caitype = CAI_L3CACHE; | |
1029 | else | 1028 | else | |
1030 | caitype = -1; | 1029 | caitype = -1; | |
1031 | break; | 1030 | break; | |
1032 | default: | 1031 | default: | |
1033 | caitype = -1; | 1032 | caitype = -1; | |
1034 | break; | 1033 | break; | |
1035 | } | 1034 | } | |
1036 | if (caitype == -1) { | 1035 | if (caitype == -1) { | |
1037 | aprint_error_dev(ci->ci_dev, | 1036 | aprint_error_dev(ci->ci_dev, | |
1038 | "error: unknown cache level&type (%d & %d)\n", | 1037 | "error: unknown cache level&type (%d & %d)\n", | |
1039 | level, type); | 1038 | level, type); | |
1040 | continue; | 1039 | continue; | |
1041 | } | 1040 | } | |
1042 | ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1; | 1041 | ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1; | |
1043 | partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS) | 1042 | partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS) | |
1044 | + 1; | 1043 | + 1; | |
1045 | linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE) | 1044 | linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE) | |
1046 | + 1; | 1045 | + 1; | |
1047 | sets = descs[2] + 1; | 1046 | sets = descs[2] + 1; | |
1048 | totalsize = ways * partitions * linesize * sets; | 1047 | totalsize = ways * partitions * linesize * sets; | |
1049 | ci->ci_cinfo[caitype].cai_totalsize = totalsize; | 1048 | ci->ci_cinfo[caitype].cai_totalsize = totalsize; | |
1050 | ci->ci_cinfo[caitype].cai_associativity = ways; | 1049 | ci->ci_cinfo[caitype].cai_associativity = ways; | |
1051 | ci->ci_cinfo[caitype].cai_linesize = linesize; | 1050 | ci->ci_cinfo[caitype].cai_linesize = linesize; | |
1052 | } | 1051 | } | |
1053 | } | 1052 | } | |
1054 | 1053 | |||
1055 | static void | 1054 | static void | |
1056 | intel_cpu_cacheinfo(struct cpu_info *ci) | 1055 | intel_cpu_cacheinfo(struct cpu_info *ci) | |
1057 | { | 1056 | { | |
1058 | const struct x86_cache_info *cai; | 1057 | const struct x86_cache_info *cai; | |
1059 | u_int descs[4]; | 1058 | u_int descs[4]; | |
1060 | int iterations, i, j; | 1059 | int iterations, i, j; | |
1061 | int type, level, ways, linesize, sets; | 1060 | int type, level, ways, linesize, sets; | |
1062 | int caitype = -1; | 1061 | int caitype = -1; | |
1063 | uint8_t desc; | 1062 | uint8_t desc; | |
1064 | 1063 | |||
1065 | /* Return if the cpu is old pre-cpuid instruction cpu */ | 1064 | /* Return if the cpu is old pre-cpuid instruction cpu */ | |
1066 | if (ci->ci_cpu_type >= 0) | 1065 | if (ci->ci_cpu_type >= 0) | |
1067 | return; | 1066 | return; | |
1068 | 1067 | |||
1069 | if (ci->ci_cpuid_level < 2) | 1068 | if (ci->ci_cpuid_level < 2) | |
1070 | return; | 1069 | return; | |
1071 | 1070 | |||
1072 | /* | 1071 | /* | |
1073 | * Parse the cache info from `cpuid leaf 2', if we have it. | 1072 | * Parse the cache info from `cpuid leaf 2', if we have it. | |
1074 | * XXX This is kinda ugly, but hey, so is the architecture... | 1073 | * XXX This is kinda ugly, but hey, so is the architecture... | |
1075 | */ | 1074 | */ | |
1076 | x86_cpuid(2, descs); | 1075 | x86_cpuid(2, descs); | |
1077 | iterations = descs[0] & 0xff; | 1076 | iterations = descs[0] & 0xff; | |
1078 | while (iterations-- > 0) { | 1077 | while (iterations-- > 0) { | |
1079 | for (i = 0; i < 4; i++) { | 1078 | for (i = 0; i < 4; i++) { | |
1080 | if (descs[i] & 0x80000000) | 1079 | if (descs[i] & 0x80000000) | |
1081 | continue; | 1080 | continue; | |
1082 | for (j = 0; j < 4; j++) { | 1081 | for (j = 0; j < 4; j++) { | |
1083 | /* | 1082 | /* | |
1084 | * The least significant byte in EAX | 1083 | * The least significant byte in EAX | |
1085 | * ((desc[0] >> 0) & 0xff) is always 0x01 and | 1084 | * ((desc[0] >> 0) & 0xff) is always 0x01 and | |
1086 | * it should be ignored. | 1085 | * it should be ignored. | |
1087 | */ | 1086 | */ | |
1088 | if (i == 0 && j == 0) | 1087 | if (i == 0 && j == 0) | |
1089 | continue; | 1088 | continue; | |
1090 | desc = (descs[i] >> (j * 8)) & 0xff; | 1089 | desc = (descs[i] >> (j * 8)) & 0xff; | |
1091 | if (desc == 0) | 1090 | if (desc == 0) | |
1092 | continue; | 1091 | continue; | |
1093 | cai = cache_info_lookup(intel_cpuid_cache_info, | 1092 | cai = cache_info_lookup(intel_cpuid_cache_info, | |
1094 | desc); | 1093 | desc); | |
1095 | if (cai != NULL) | 1094 | if (cai != NULL) | |
1096 | ci->ci_cinfo[cai->cai_index] = *cai; | 1095 | ci->ci_cinfo[cai->cai_index] = *cai; | |
1097 | else if ((verbose != 0) && (desc != 0xff) | 1096 | else if ((verbose != 0) && (desc != 0xff) | |
1098 | && (desc != 0xfe)) | 1097 | && (desc != 0xfe)) | |
1099 | aprint_error_dev(ci->ci_dev, "error:" | 1098 | aprint_error_dev(ci->ci_dev, "error:" | |
1100 | " Unknown cacheinfo desc %02x\n", | 1099 | " Unknown cacheinfo desc %02x\n", | |
1101 | desc); | 1100 | desc); | |
1102 | } | 1101 | } | |
1103 | } | 1102 | } | |
1104 | x86_cpuid(2, descs); | 1103 | x86_cpuid(2, descs); | |
1105 | } | 1104 | } | |
1106 | 1105 | |||
1107 | if (ci->ci_cpuid_level < 4) | 1106 | if (ci->ci_cpuid_level < 4) | |
1108 | return; | 1107 | return; | |
1109 | 1108 | |||
1110 | /* Parse the cache info from `cpuid leaf 4', if we have it. */ | 1109 | /* Parse the cache info from `cpuid leaf 4', if we have it. */ | |
1111 | cpu_dcp_cacheinfo(ci, 4); | 1110 | cpu_dcp_cacheinfo(ci, 4); | |
1112 | 1111 | |||
1113 | if (ci->ci_cpuid_level < 0x18) | 1112 | if (ci->ci_cpuid_level < 0x18) | |
1114 | return; | 1113 | return; | |
1115 | /* Parse the TLB info from `cpuid leaf 18H', if we have it. */ | 1114 | /* Parse the TLB info from `cpuid leaf 18H', if we have it. */ | |
1116 | x86_cpuid(0x18, descs); | 1115 | x86_cpuid(0x18, descs); | |
1117 | iterations = descs[0]; | 1116 | iterations = descs[0]; | |
1118 | for (i = 0; i <= iterations; i++) { | 1117 | for (i = 0; i <= iterations; i++) { | |
1119 | uint32_t pgsize; | 1118 | uint32_t pgsize; | |
1120 | bool full; | 1119 | bool full; | |
1121 | 1120 | |||
1122 | x86_cpuid2(0x18, i, descs); | 1121 | x86_cpuid2(0x18, i, descs); | |
1123 | type = __SHIFTOUT(descs[3], CPUID_DATP_TCTYPE); | 1122 | type = __SHIFTOUT(descs[3], CPUID_DATP_TCTYPE); | |
1124 | if (type == CPUID_DATP_TCTYPE_N) | 1123 | if (type == CPUID_DATP_TCTYPE_N) | |
1125 | continue; | 1124 | continue; | |
1126 | level = __SHIFTOUT(descs[3], CPUID_DATP_TCLEVEL); | 1125 | level = __SHIFTOUT(descs[3], CPUID_DATP_TCLEVEL); | |
1127 | pgsize = __SHIFTOUT(descs[1], CPUID_DATP_PGSIZE); | 1126 | pgsize = __SHIFTOUT(descs[1], CPUID_DATP_PGSIZE); | |
1128 | switch (level) { | 1127 | switch (level) { | |
1129 | case 1: | 1128 | case 1: | |
1130 | if (type == CPUID_DATP_TCTYPE_I) { | 1129 | if (type == CPUID_DATP_TCTYPE_I) { | |
1131 | switch (pgsize) { | 1130 | switch (pgsize) { | |
1132 | case CPUID_DATP_PGSIZE_4KB: | 1131 | case CPUID_DATP_PGSIZE_4KB: | |
1133 | caitype = CAI_ITLB; | 1132 | caitype = CAI_ITLB; | |
1134 | break; | 1133 | break; | |
1135 | case CPUID_DATP_PGSIZE_2MB | 1134 | case CPUID_DATP_PGSIZE_2MB | |
1136 | | CPUID_DATP_PGSIZE_4MB: | 1135 | | CPUID_DATP_PGSIZE_4MB: | |
1137 | caitype = CAI_ITLB2; | 1136 | caitype = CAI_ITLB2; | |
1138 | break; | 1137 | break; | |
1139 | case CPUID_DATP_PGSIZE_1GB: | 1138 | case CPUID_DATP_PGSIZE_1GB: | |
1140 | caitype = CAI_L1_1GBITLB; | 1139 | caitype = CAI_L1_1GBITLB; | |
1141 | break; | 1140 | break; | |
1142 | default: | 1141 | default: | |
1143 | aprint_error_dev(ci->ci_dev, | 1142 | aprint_error_dev(ci->ci_dev, | |
1144 | "error: unknown ITLB size (%d)\n", | 1143 | "error: unknown ITLB size (%d)\n", | |
1145 | pgsize); | 1144 | pgsize); | |
1146 | caitype = CAI_ITLB; | 1145 | caitype = CAI_ITLB; | |
1147 | break; | 1146 | break; | |
1148 | } | 1147 | } | |
1149 | } else if (type == CPUID_DATP_TCTYPE_D) { | 1148 | } else if (type == CPUID_DATP_TCTYPE_D) { | |
1150 | switch (pgsize) { | 1149 | switch (pgsize) { | |
1151 | case CPUID_DATP_PGSIZE_4KB: | 1150 | case CPUID_DATP_PGSIZE_4KB: | |
1152 | caitype = CAI_DTLB; | 1151 | caitype = CAI_DTLB; | |
1153 | break; | 1152 | break; | |
1154 | case CPUID_DATP_PGSIZE_2MB | 1153 | case CPUID_DATP_PGSIZE_2MB | |
1155 | | CPUID_DATP_PGSIZE_4MB: | 1154 | | CPUID_DATP_PGSIZE_4MB: | |
1156 | caitype = CAI_DTLB2; | 1155 | caitype = CAI_DTLB2; | |
1157 | break; | 1156 | break; | |
1158 | case CPUID_DATP_PGSIZE_1GB: | 1157 | case CPUID_DATP_PGSIZE_1GB: | |
1159 | caitype = CAI_L1_1GBDTLB; | 1158 | caitype = CAI_L1_1GBDTLB; | |
1160 | break; | 1159 | break; | |
1161 | default: | 1160 | default: | |
1162 | aprint_error_dev(ci->ci_dev, | 1161 | aprint_error_dev(ci->ci_dev, | |
1163 | "error: unknown DTLB size (%d)\n", | 1162 | "error: unknown DTLB size (%d)\n", | |
1164 | pgsize); | 1163 | pgsize); | |
1165 | caitype = CAI_DTLB; | 1164 | caitype = CAI_DTLB; | |
1166 | break; | 1165 | break; | |
1167 | } | 1166 | } | |
1168 | } else | 1167 | } else | |
1169 | caitype = -1; | 1168 | caitype = -1; | |
1170 | break; | 1169 | break; | |
1171 | case 2: | 1170 | case 2: | |
1172 | if (type == CPUID_DATP_TCTYPE_I) | 1171 | if (type == CPUID_DATP_TCTYPE_I) | |
1173 | caitype = CAI_L2_ITLB; | 1172 | caitype = CAI_L2_ITLB; | |
1174 | else if (type == CPUID_DATP_TCTYPE_D) | 1173 | else if (type == CPUID_DATP_TCTYPE_D) | |
1175 | caitype = CAI_L2_DTLB; | 1174 | caitype = CAI_L2_DTLB; | |
1176 | else if (type == CPUID_DATP_TCTYPE_U) { | 1175 | else if (type == CPUID_DATP_TCTYPE_U) { | |
1177 | switch (pgsize) { | 1176 | switch (pgsize) { | |
1178 | case CPUID_DATP_PGSIZE_4KB: | 1177 | case CPUID_DATP_PGSIZE_4KB: | |
1179 | caitype = CAI_L2_STLB; | 1178 | caitype = CAI_L2_STLB; | |
1180 | break; | 1179 | break; | |
1181 | case CPUID_DATP_PGSIZE_4KB | 1180 | case CPUID_DATP_PGSIZE_4KB | |
1182 | | CPUID_DATP_PGSIZE_2MB: | 1181 | | CPUID_DATP_PGSIZE_2MB: | |
1183 | caitype = CAI_L2_STLB2; | 1182 | caitype = CAI_L2_STLB2; | |
1184 | break; | 1183 | break; | |
1185 | case CPUID_DATP_PGSIZE_2MB | 1184 | case CPUID_DATP_PGSIZE_2MB | |
1186 | | CPUID_DATP_PGSIZE_4MB: | 1185 | | CPUID_DATP_PGSIZE_4MB: | |
1187 | caitype = CAI_L2_STLB3; | 1186 | caitype = CAI_L2_STLB3; | |
1188 | break; | 1187 | break; | |
1189 | default: | 1188 | default: | |
1190 | aprint_error_dev(ci->ci_dev, | 1189 | aprint_error_dev(ci->ci_dev, | |
1191 | "error: unknown L2 STLB size (%d)\n", | 1190 | "error: unknown L2 STLB size (%d)\n", | |
1192 | pgsize); | 1191 | pgsize); | |
1193 | caitype = CAI_DTLB; | 1192 | caitype = CAI_DTLB; | |
1194 | break; | 1193 | break; | |
1195 | } | 1194 | } | |
1196 | } else | 1195 | } else | |
1197 | caitype = -1; | 1196 | caitype = -1; | |
1198 | break; | 1197 | break; | |
1199 | case 3: | 1198 | case 3: | |
1200 | /* XXX need work for L3 TLB */ | 1199 | /* XXX need work for L3 TLB */ | |
1201 | caitype = CAI_L3CACHE; | 1200 | caitype = CAI_L3CACHE; | |
1202 | break; | 1201 | break; | |
1203 | default: | 1202 | default: | |
1204 | caitype = -1; | 1203 | caitype = -1; | |
1205 | break; | 1204 | break; | |
1206 | } | 1205 | } | |
1207 | if (caitype == -1) { | 1206 | if (caitype == -1) { | |
1208 | aprint_error_dev(ci->ci_dev, | 1207 | aprint_error_dev(ci->ci_dev, | |
1209 | "error: unknown TLB level&type (%d & %d)\n", | 1208 | "error: unknown TLB level&type (%d & %d)\n", | |
1210 | level, type); | 1209 | level, type); | |
1211 | continue; | 1210 | continue; | |
1212 | } | 1211 | } | |
1213 | switch (pgsize) { | 1212 | switch (pgsize) { | |
1214 | case CPUID_DATP_PGSIZE_4KB: | 1213 | case CPUID_DATP_PGSIZE_4KB: | |
1215 | linesize = 4 * 1024; | 1214 | linesize = 4 * 1024; | |
1216 | break; | 1215 | break; | |
1217 | case CPUID_DATP_PGSIZE_2MB: | 1216 | case CPUID_DATP_PGSIZE_2MB: | |
1218 | linesize = 2 * 1024 * 1024; | 1217 | linesize = 2 * 1024 * 1024; | |
1219 | break; | 1218 | break; | |
1220 | case CPUID_DATP_PGSIZE_4MB: | 1219 | case CPUID_DATP_PGSIZE_4MB: | |
1221 | linesize = 4 * 1024 * 1024; | 1220 | linesize = 4 * 1024 * 1024; | |
1222 | break; | 1221 | break; | |
1223 | case CPUID_DATP_PGSIZE_1GB: | 1222 | case CPUID_DATP_PGSIZE_1GB: | |
1224 | linesize = 1024 * 1024 * 1024; | 1223 | linesize = 1024 * 1024 * 1024; | |
1225 | break; | 1224 | break; | |
1226 | case CPUID_DATP_PGSIZE_2MB | CPUID_DATP_PGSIZE_4MB: | 1225 | case CPUID_DATP_PGSIZE_2MB | CPUID_DATP_PGSIZE_4MB: | |
1227 | aprint_error_dev(ci->ci_dev, | 1226 | aprint_error_dev(ci->ci_dev, | |
1228 | "WARINING: Currently 2M/4M info can't print correctly\n"); | 1227 | "WARINING: Currently 2M/4M info can't print correctly\n"); | |
1229 | linesize = 4 * 1024 * 1024; | 1228 | linesize = 4 * 1024 * 1024; | |
1230 | break; | 1229 | break; | |
1231 | default: | 1230 | default: | |
1232 | aprint_error_dev(ci->ci_dev, | 1231 | aprint_error_dev(ci->ci_dev, | |
1233 | "error: Unknown size combination\n"); | 1232 | "error: Unknown size combination\n"); | |
1234 | linesize = 4 * 1024; | 1233 | linesize = 4 * 1024; | |
1235 | break; | 1234 | break; | |
1236 | } | 1235 | } | |
1237 | ways = __SHIFTOUT(descs[1], CPUID_DATP_WAYS); | 1236 | ways = __SHIFTOUT(descs[1], CPUID_DATP_WAYS); | |
1238 | sets = descs[2]; | 1237 | sets = descs[2]; | |
1239 | full = descs[3] & CPUID_DATP_FULLASSOC; | 1238 | full = descs[3] & CPUID_DATP_FULLASSOC; | |
1240 | ci->ci_cinfo[caitype].cai_totalsize | 1239 | ci->ci_cinfo[caitype].cai_totalsize | |
1241 | = ways * sets; /* entries */ | 1240 | = ways * sets; /* entries */ | |
1242 | ci->ci_cinfo[caitype].cai_associativity | 1241 | ci->ci_cinfo[caitype].cai_associativity | |
1243 | = full ? 0xff : ways; | 1242 | = full ? 0xff : ways; | |
1244 | ci->ci_cinfo[caitype].cai_linesize = linesize; /* pg size */ | 1243 | ci->ci_cinfo[caitype].cai_linesize = linesize; /* pg size */ | |
1245 | } | 1244 | } | |
1246 | } | 1245 | } | |
1247 | 1246 | |||
1248 | static const struct x86_cache_info amd_cpuid_l2l3cache_assoc_info[] = | 1247 | static const struct x86_cache_info amd_cpuid_l2l3cache_assoc_info[] = | |
1249 | AMD_L2L3CACHE_INFO; | 1248 | AMD_L2L3CACHE_INFO; | |
1250 | 1249 | |||
1251 | static void | 1250 | static void | |
1252 | amd_cpu_cacheinfo(struct cpu_info *ci) | 1251 | amd_cpu_cacheinfo(struct cpu_info *ci) | |
1253 | { | 1252 | { | |
1254 | const struct x86_cache_info *cp; | 1253 | const struct x86_cache_info *cp; | |
1255 | struct x86_cache_info *cai; | 1254 | struct x86_cache_info *cai; | |
1256 | u_int descs[4]; | 1255 | u_int descs[4]; | |
1257 | u_int lfunc; | 1256 | u_int lfunc; | |
1258 | 1257 | |||
1259 | /* K5 model 0 has none of this info. */ | 1258 | /* K5 model 0 has none of this info. */ | |
1260 | if (ci->ci_family == 5 && ci->ci_model == 0) | 1259 | if (ci->ci_family == 5 && ci->ci_model == 0) | |
1261 | return; | 1260 | return; | |
1262 | 1261 | |||
1263 | /* Determine the largest extended function value. */ | 1262 | /* Determine the largest extended function value. */ | |
1264 | x86_cpuid(0x80000000, descs); | 1263 | x86_cpuid(0x80000000, descs); | |
1265 | lfunc = descs[0]; | 1264 | lfunc = descs[0]; | |
1266 | 1265 | |||
1267 | if (lfunc < 0x80000005) | 1266 | if (lfunc < 0x80000005) | |
1268 | return; | 1267 | return; | |
1269 | 1268 | |||
1270 | /* Determine L1 cache/TLB info. */ | 1269 | /* Determine L1 cache/TLB info. */ | |
1271 | x86_cpuid(0x80000005, descs); | 1270 | x86_cpuid(0x80000005, descs); | |
1272 | 1271 | |||
1273 | /* K6-III and higher have large page TLBs. */ | 1272 | /* K6-III and higher have large page TLBs. */ | |
1274 | if ((ci->ci_family == 5 && ci->ci_model >= 9) || ci->ci_family >= 6) { | 1273 | if ((ci->ci_family == 5 && ci->ci_model >= 9) || ci->ci_family >= 6) { | |
1275 | cai = &ci->ci_cinfo[CAI_ITLB2]; | 1274 | cai = &ci->ci_cinfo[CAI_ITLB2]; | |
1276 | cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); | 1275 | cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]); | |
1277 | cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); | 1276 | cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]); | |
1278 | cai->cai_linesize = largepagesize; | 1277 | cai->cai_linesize = largepagesize; | |
1279 | 1278 | |||
1280 | cai = &ci->ci_cinfo[CAI_DTLB2]; | 1279 | cai = &ci->ci_cinfo[CAI_DTLB2]; | |
1281 | cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); | 1280 | cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]); | |
1282 | cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); | 1281 | cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]); | |
1283 | cai->cai_linesize = largepagesize; | 1282 | cai->cai_linesize = largepagesize; | |
1284 | } | 1283 | } | |
1285 | 1284 | |||
1286 | cai = &ci->ci_cinfo[CAI_ITLB]; | 1285 | cai = &ci->ci_cinfo[CAI_ITLB]; | |
1287 | cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); | 1286 | cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]); | |
1288 | cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); | 1287 | cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]); | |
1289 | cai->cai_linesize = (4 * 1024); | 1288 | cai->cai_linesize = (4 * 1024); | |
1290 | 1289 | |||
1291 | cai = &ci->ci_cinfo[CAI_DTLB]; | 1290 | cai = &ci->ci_cinfo[CAI_DTLB]; | |
1292 | cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); | 1291 | cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]); | |
1293 | cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); | 1292 | cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]); | |
1294 | cai->cai_linesize = (4 * 1024); | 1293 | cai->cai_linesize = (4 * 1024); | |
1295 | 1294 | |||
1296 | cai = &ci->ci_cinfo[CAI_DCACHE]; | 1295 | cai = &ci->ci_cinfo[CAI_DCACHE]; | |
1297 | cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); | 1296 | cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]); | |
1298 | cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); | 1297 | cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]); | |
1299 | cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]); | 1298 | cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]); | |
1300 | 1299 | |||
1301 | cai = &ci->ci_cinfo[CAI_ICACHE]; | 1300 | cai = &ci->ci_cinfo[CAI_ICACHE]; | |
1302 | cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); | 1301 | cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]); | |
1303 | cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); | 1302 | cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]); | |
1304 | cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); | 1303 | cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]); | |
1305 | 1304 | |||
1306 | if (lfunc < 0x80000006) | 1305 | if (lfunc < 0x80000006) | |
1307 | return; | 1306 | return; | |
1308 | 1307 | |||
1309 | /* Determine L2 cache/TLB info. */ | 1308 | /* Determine L2 cache/TLB info. */ | |
1310 | x86_cpuid(0x80000006, descs); | 1309 | x86_cpuid(0x80000006, descs); | |
1311 | 1310 | |||
1312 | cai = &ci->ci_cinfo[CAI_L2_ITLB]; | 1311 | cai = &ci->ci_cinfo[CAI_L2_ITLB]; | |
1313 | cai->cai_totalsize = AMD_L2_EBX_IUTLB_ENTRIES(descs[1]); | 1312 | cai->cai_totalsize = AMD_L2_EBX_IUTLB_ENTRIES(descs[1]); | |
1314 | cai->cai_associativity = AMD_L2_EBX_IUTLB_ASSOC(descs[1]); | 1313 | cai->cai_associativity = AMD_L2_EBX_IUTLB_ASSOC(descs[1]); | |
1315 | cai->cai_linesize = (4 * 1024); | 1314 | cai->cai_linesize = (4 * 1024); | |
1316 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1315 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1317 | cai->cai_associativity); | 1316 | cai->cai_associativity); | |
1318 | if (cp != NULL) | 1317 | if (cp != NULL) | |
1319 | cai->cai_associativity = cp->cai_associativity; | 1318 | cai->cai_associativity = cp->cai_associativity; | |
1320 | else | 1319 | else | |
1321 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1320 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1322 | 1321 | |||
1323 | cai = &ci->ci_cinfo[CAI_L2_ITLB2]; | 1322 | cai = &ci->ci_cinfo[CAI_L2_ITLB2]; | |
1324 | cai->cai_totalsize = AMD_L2_EAX_IUTLB_ENTRIES(descs[0]); | 1323 | cai->cai_totalsize = AMD_L2_EAX_IUTLB_ENTRIES(descs[0]); | |
1325 | cai->cai_associativity = AMD_L2_EAX_IUTLB_ASSOC(descs[0]); | 1324 | cai->cai_associativity = AMD_L2_EAX_IUTLB_ASSOC(descs[0]); | |
1326 | cai->cai_linesize = largepagesize; | 1325 | cai->cai_linesize = largepagesize; | |
1327 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1326 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1328 | cai->cai_associativity); | 1327 | cai->cai_associativity); | |
1329 | if (cp != NULL) | 1328 | if (cp != NULL) | |
1330 | cai->cai_associativity = cp->cai_associativity; | 1329 | cai->cai_associativity = cp->cai_associativity; | |
1331 | else | 1330 | else | |
1332 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1331 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1333 | 1332 | |||
1334 | cai = &ci->ci_cinfo[CAI_L2_DTLB]; | 1333 | cai = &ci->ci_cinfo[CAI_L2_DTLB]; | |
1335 | cai->cai_totalsize = AMD_L2_EBX_DTLB_ENTRIES(descs[1]); | 1334 | cai->cai_totalsize = AMD_L2_EBX_DTLB_ENTRIES(descs[1]); | |
1336 | cai->cai_associativity = AMD_L2_EBX_DTLB_ASSOC(descs[1]); | 1335 | cai->cai_associativity = AMD_L2_EBX_DTLB_ASSOC(descs[1]); | |
1337 | cai->cai_linesize = (4 * 1024); | 1336 | cai->cai_linesize = (4 * 1024); | |
1338 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1337 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1339 | cai->cai_associativity); | 1338 | cai->cai_associativity); | |
1340 | if (cp != NULL) | 1339 | if (cp != NULL) | |
1341 | cai->cai_associativity = cp->cai_associativity; | 1340 | cai->cai_associativity = cp->cai_associativity; | |
1342 | else | 1341 | else | |
1343 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1342 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1344 | 1343 | |||
1345 | cai = &ci->ci_cinfo[CAI_L2_DTLB2]; | 1344 | cai = &ci->ci_cinfo[CAI_L2_DTLB2]; | |
1346 | cai->cai_totalsize = AMD_L2_EAX_DTLB_ENTRIES(descs[0]); | 1345 | cai->cai_totalsize = AMD_L2_EAX_DTLB_ENTRIES(descs[0]); | |
1347 | cai->cai_associativity = AMD_L2_EAX_DTLB_ASSOC(descs[0]); | 1346 | cai->cai_associativity = AMD_L2_EAX_DTLB_ASSOC(descs[0]); | |
1348 | cai->cai_linesize = largepagesize; | 1347 | cai->cai_linesize = largepagesize; | |
1349 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1348 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1350 | cai->cai_associativity); | 1349 | cai->cai_associativity); | |
1351 | if (cp != NULL) | 1350 | if (cp != NULL) | |
1352 | cai->cai_associativity = cp->cai_associativity; | 1351 | cai->cai_associativity = cp->cai_associativity; | |
1353 | else | 1352 | else | |
1354 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1353 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1355 | 1354 | |||
1356 | cai = &ci->ci_cinfo[CAI_L2CACHE]; | 1355 | cai = &ci->ci_cinfo[CAI_L2CACHE]; | |
1357 | cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); | 1356 | cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]); | |
1358 | cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); | 1357 | cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]); | |
1359 | cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); | 1358 | cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]); | |
1360 | 1359 | |||
1361 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1360 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1362 | cai->cai_associativity); | 1361 | cai->cai_associativity); | |
1363 | if (cp != NULL) | 1362 | if (cp != NULL) | |
1364 | cai->cai_associativity = cp->cai_associativity; | 1363 | cai->cai_associativity = cp->cai_associativity; | |
1365 | else | 1364 | else | |
1366 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1365 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1367 | 1366 | |||
1368 | /* Determine L3 cache info on AMD Family 10h and newer processors */ | 1367 | /* Determine L3 cache info on AMD Family 10h and newer processors */ | |
1369 | if (ci->ci_family >= 0x10) { | 1368 | if (ci->ci_family >= 0x10) { | |
1370 | cai = &ci->ci_cinfo[CAI_L3CACHE]; | 1369 | cai = &ci->ci_cinfo[CAI_L3CACHE]; | |
1371 | cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); | 1370 | cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]); | |
1372 | cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); | 1371 | cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]); | |
1373 | cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); | 1372 | cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]); | |
1374 | 1373 | |||
1375 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1374 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1376 | cai->cai_associativity); | 1375 | cai->cai_associativity); | |
1377 | if (cp != NULL) | 1376 | if (cp != NULL) | |
1378 | cai->cai_associativity = cp->cai_associativity; | 1377 | cai->cai_associativity = cp->cai_associativity; | |
1379 | else | 1378 | else | |
1380 | cai->cai_associativity = 0; /* XXX Unkn/Rsvd */ | 1379 | cai->cai_associativity = 0; /* XXX Unkn/Rsvd */ | |
1381 | } | 1380 | } | |
1382 | 1381 | |||
1383 | if (lfunc < 0x80000019) | 1382 | if (lfunc < 0x80000019) | |
1384 | return; | 1383 | return; | |
1385 | 1384 | |||
1386 | /* Determine 1GB TLB info. */ | 1385 | /* Determine 1GB TLB info. */ | |
1387 | x86_cpuid(0x80000019, descs); | 1386 | x86_cpuid(0x80000019, descs); | |
1388 | 1387 | |||
1389 | cai = &ci->ci_cinfo[CAI_L1_1GBITLB]; | 1388 | cai = &ci->ci_cinfo[CAI_L1_1GBITLB]; | |
1390 | cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]); | 1389 | cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]); | |
1391 | cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]); | 1390 | cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]); | |
1392 | cai->cai_linesize = (1024 * 1024 * 1024); | 1391 | cai->cai_linesize = (1024 * 1024 * 1024); | |
1393 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1392 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1394 | cai->cai_associativity); | 1393 | cai->cai_associativity); | |
1395 | if (cp != NULL) | 1394 | if (cp != NULL) | |
1396 | cai->cai_associativity = cp->cai_associativity; | 1395 | cai->cai_associativity = cp->cai_associativity; | |
1397 | else | 1396 | else | |
1398 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1397 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1399 | 1398 | |||
1400 | cai = &ci->ci_cinfo[CAI_L1_1GBDTLB]; | 1399 | cai = &ci->ci_cinfo[CAI_L1_1GBDTLB]; | |
1401 | cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[0]); | 1400 | cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[0]); | |
1402 | cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[0]); | 1401 | cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[0]); | |
1403 | cai->cai_linesize = (1024 * 1024 * 1024); | 1402 | cai->cai_linesize = (1024 * 1024 * 1024); | |
1404 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1403 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1405 | cai->cai_associativity); | 1404 | cai->cai_associativity); | |
1406 | if (cp != NULL) | 1405 | if (cp != NULL) | |
1407 | cai->cai_associativity = cp->cai_associativity; | 1406 | cai->cai_associativity = cp->cai_associativity; | |
1408 | else | 1407 | else | |
1409 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1408 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1410 | 1409 | |||
1411 | cai = &ci->ci_cinfo[CAI_L2_1GBITLB]; | 1410 | cai = &ci->ci_cinfo[CAI_L2_1GBITLB]; | |
1412 | cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[1]); | 1411 | cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[1]); | |
1413 | cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[1]); | 1412 | cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[1]); | |
1414 | cai->cai_linesize = (1024 * 1024 * 1024); | 1413 | cai->cai_linesize = (1024 * 1024 * 1024); | |
1415 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1414 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1416 | cai->cai_associativity); | 1415 | cai->cai_associativity); | |
1417 | if (cp != NULL) | 1416 | if (cp != NULL) | |
1418 | cai->cai_associativity = cp->cai_associativity; | 1417 | cai->cai_associativity = cp->cai_associativity; | |
1419 | else | 1418 | else | |
1420 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1419 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1421 | 1420 | |||
1422 | cai = &ci->ci_cinfo[CAI_L2_1GBDTLB]; | 1421 | cai = &ci->ci_cinfo[CAI_L2_1GBDTLB]; | |
1423 | cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]); | 1422 | cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]); | |
1424 | cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]); | 1423 | cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]); | |
1425 | cai->cai_linesize = (1024 * 1024 * 1024); | 1424 | cai->cai_linesize = (1024 * 1024 * 1024); | |
1426 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | 1425 | cp = cache_info_lookup(amd_cpuid_l2l3cache_assoc_info, | |
1427 | cai->cai_associativity); | 1426 | cai->cai_associativity); | |
1428 | if (cp != NULL) | 1427 | if (cp != NULL) | |
1429 | cai->cai_associativity = cp->cai_associativity; | 1428 | cai->cai_associativity = cp->cai_associativity; | |
1430 | else | 1429 | else | |
1431 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | 1430 | cai->cai_associativity = 0; /* XXX Unknown/reserved */ | |
1432 | 1431 | |||
1433 | if (lfunc < 0x8000001d) | 1432 | if (lfunc < 0x8000001d) | |
1434 | return; | 1433 | return; | |
1435 | 1434 | |||
1436 | if (ci->ci_feat_val[3] & CPUID_TOPOEXT) | 1435 | if (ci->ci_feat_val[3] & CPUID_TOPOEXT) | |
1437 | cpu_dcp_cacheinfo(ci, 0x8000001d); | 1436 | cpu_dcp_cacheinfo(ci, 0x8000001d); | |
1438 | } | 1437 | } | |
1439 | 1438 | |||
1440 | static void | 1439 | static void | |
1441 | via_cpu_cacheinfo(struct cpu_info *ci) | 1440 | via_cpu_cacheinfo(struct cpu_info *ci) | |
1442 | { | 1441 | { | |
1443 | struct x86_cache_info *cai; | 1442 | struct x86_cache_info *cai; | |
1444 | int stepping; | 1443 | int stepping; | |
1445 | u_int descs[4]; | 1444 | u_int descs[4]; | |
1446 | u_int lfunc; | 1445 | u_int lfunc; | |
1447 | 1446 | |||
1448 | stepping = CPUID_TO_STEPPING(ci->ci_signature); | 1447 | stepping = CPUID_TO_STEPPING(ci->ci_signature); | |
1449 | 1448 | |||
1450 | /* | 1449 | /* | |
1451 | * Determine the largest extended function value. | 1450 | * Determine the largest extended function value. | |
1452 | */ | 1451 | */ | |
1453 | x86_cpuid(0x80000000, descs); | 1452 | x86_cpuid(0x80000000, descs); | |
1454 | lfunc = descs[0]; | 1453 | lfunc = descs[0]; | |
1455 | 1454 | |||
1456 | /* | 1455 | /* | |
1457 | * Determine L1 cache/TLB info. | 1456 | * Determine L1 cache/TLB info. | |
1458 | */ | 1457 | */ | |
1459 | if (lfunc < 0x80000005) { | 1458 | if (lfunc < 0x80000005) { | |
1460 | /* No L1 cache info available. */ | 1459 | /* No L1 cache info available. */ | |
1461 | return; | 1460 | return; | |
1462 | } | 1461 | } | |
1463 | 1462 | |||
1464 | x86_cpuid(0x80000005, descs); | 1463 | x86_cpuid(0x80000005, descs); | |
1465 | 1464 | |||
1466 | cai = &ci->ci_cinfo[CAI_ITLB]; | 1465 | cai = &ci->ci_cinfo[CAI_ITLB]; | |
1467 | cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); | 1466 | cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]); | |
1468 | cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); | 1467 | cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]); | |
1469 | cai->cai_linesize = (4 * 1024); | 1468 | cai->cai_linesize = (4 * 1024); | |
1470 | 1469 | |||
1471 | cai = &ci->ci_cinfo[CAI_DTLB]; | 1470 | cai = &ci->ci_cinfo[CAI_DTLB]; | |
1472 | cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); | 1471 | cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]); | |
1473 | cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); | 1472 | cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]); | |
1474 | cai->cai_linesize = (4 * 1024); | 1473 | cai->cai_linesize = (4 * 1024); | |
1475 | 1474 | |||
1476 | cai = &ci->ci_cinfo[CAI_DCACHE]; | 1475 | cai = &ci->ci_cinfo[CAI_DCACHE]; | |
1477 | cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); | 1476 | cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]); | |
1478 | cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); | 1477 | cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]); | |
1479 | cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); | 1478 | cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]); | |
1480 | if (ci->ci_model == 9 && stepping == 8) { | 1479 | if (ci->ci_model == 9 && stepping == 8) { | |
1481 | /* Erratum: stepping 8 reports 4 when it should be 2 */ | 1480 | /* Erratum: stepping 8 reports 4 when it should be 2 */ | |
1482 | cai->cai_associativity = 2; | 1481 | cai->cai_associativity = 2; | |
1483 | } | 1482 | } | |
1484 | 1483 | |||
1485 | cai = &ci->ci_cinfo[CAI_ICACHE]; | 1484 | cai = &ci->ci_cinfo[CAI_ICACHE]; | |
1486 | cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); | 1485 | cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); | |
1487 | cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); | 1486 | cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); | |
1488 | cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); | 1487 | cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); | |
1489 | if (ci->ci_model == 9 && stepping == 8) { | 1488 | if (ci->ci_model == 9 && stepping == 8) { | |
1490 | /* Erratum: stepping 8 reports 4 when it should be 2 */ | 1489 | /* Erratum: stepping 8 reports 4 when it should be 2 */ | |
1491 | cai->cai_associativity = 2; | 1490 | cai->cai_associativity = 2; | |
1492 | } | 1491 | } | |
1493 | 1492 | |||
1494 | /* | 1493 | /* | |
1495 | * Determine L2 cache/TLB info. | 1494 | * Determine L2 cache/TLB info. | |
1496 | */ | 1495 | */ | |
1497 | if (lfunc < 0x80000006) { | 1496 | if (lfunc < 0x80000006) { | |
1498 | /* No L2 cache info available. */ | 1497 | /* No L2 cache info available. */ | |
1499 | return; | 1498 | return; | |
1500 | } | 1499 | } | |
1501 | 1500 | |||
1502 | x86_cpuid(0x80000006, descs); | 1501 | x86_cpuid(0x80000006, descs); | |
1503 | 1502 | |||
1504 | cai = &ci->ci_cinfo[CAI_L2CACHE]; | 1503 | cai = &ci->ci_cinfo[CAI_L2CACHE]; | |
1505 | if (ci->ci_model >= 9) { | 1504 | if (ci->ci_model >= 9) { | |
1506 | cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); | 1505 | cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); | |
1507 | cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); | 1506 | cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]); | |
1508 | cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); | 1507 | cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]); | |
1509 | } else { | 1508 | } else { | |
1510 | cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); | 1509 | cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]); | |
1511 | cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); | 1510 | cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]); | |
1512 | cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); | 1511 | cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]); | |
1513 | } | 1512 | } | |
1514 | } | 1513 | } | |
1515 | 1514 | |||
1516 | static void | 1515 | static void | |
1517 | tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage) | 1516 | tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage) | |
1518 | { | 1517 | { | |
1519 | u_int descs[4]; | 1518 | u_int descs[4]; | |
1520 | 1519 | |||
1521 | x86_cpuid(0x80860007, descs); | 1520 | x86_cpuid(0x80860007, descs); | |
1522 | *frequency = descs[0]; | 1521 | *frequency = descs[0]; | |
1523 | *voltage = descs[1]; | 1522 | *voltage = descs[1]; | |
1524 | *percentage = descs[2]; | 1523 | *percentage = descs[2]; | |
1525 | } | 1524 | } | |
1526 | 1525 | |||
1527 | static void | 1526 | static void | |
1528 | transmeta_cpu_info(struct cpu_info *ci) | 1527 | transmeta_cpu_info(struct cpu_info *ci) | |
1529 | { | 1528 | { | |
1530 | u_int descs[4], nreg; | 1529 | u_int descs[4], nreg; | |
1531 | u_int frequency, voltage, percentage; | 1530 | u_int frequency, voltage, percentage; | |
1532 | 1531 | |||
1533 | x86_cpuid(0x80860000, descs); | 1532 | x86_cpuid(0x80860000, descs); | |
1534 | nreg = descs[0]; | 1533 | nreg = descs[0]; | |
1535 | if (nreg >= 0x80860001) { | 1534 | if (nreg >= 0x80860001) { | |
1536 | x86_cpuid(0x80860001, descs); | 1535 | x86_cpuid(0x80860001, descs); | |
1537 | aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n", | 1536 | aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n", | |
1538 | (descs[1] >> 24) & 0xff, | 1537 | (descs[1] >> 24) & 0xff, | |
1539 | (descs[1] >> 16) & 0xff, | 1538 | (descs[1] >> 16) & 0xff, | |
1540 | (descs[1] >> 8) & 0xff, | 1539 | (descs[1] >> 8) & 0xff, | |
1541 | descs[1] & 0xff); | 1540 | descs[1] & 0xff); | |
1542 | } | 1541 | } | |
1543 | if (nreg >= 0x80860002) { | 1542 | if (nreg >= 0x80860002) { | |
1544 | x86_cpuid(0x80860002, descs); | 1543 | x86_cpuid(0x80860002, descs); | |
1545 | aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n", | 1544 | aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n", | |
1546 | (descs[1] >> 24) & 0xff, | 1545 | (descs[1] >> 24) & 0xff, | |
1547 | (descs[1] >> 16) & 0xff, | 1546 | (descs[1] >> 16) & 0xff, | |
1548 | (descs[1] >> 8) & 0xff, | 1547 | (descs[1] >> 8) & 0xff, | |
1549 | descs[1] & 0xff, | 1548 | descs[1] & 0xff, | |
1550 | descs[2]); | 1549 | descs[2]); | |
1551 | } | 1550 | } | |
1552 | if (nreg >= 0x80860006) { | 1551 | if (nreg >= 0x80860006) { | |
1553 | union { | 1552 | union { | |
1554 | char text[65]; | 1553 | char text[65]; | |
1555 | u_int descs[4][4]; | 1554 | u_int descs[4][4]; | |
1556 | } info; | 1555 | } info; | |
1557 | int i; | 1556 | int i; | |
1558 | 1557 | |||
1559 | for (i=0; i<4; i++) { | 1558 | for (i=0; i<4; i++) { | |
1560 | x86_cpuid(0x80860003 + i, info.descs[i]); | 1559 | x86_cpuid(0x80860003 + i, info.descs[i]); | |
1561 | } | 1560 | } | |
1562 | info.text[64] = '\0'; | 1561 | info.text[64] = '\0'; | |
1563 | aprint_verbose_dev(ci->ci_dev, "%s\n", info.text); | 1562 | aprint_verbose_dev(ci->ci_dev, "%s\n", info.text); | |
1564 | } | 1563 | } | |
1565 | 1564 | |||
1566 | if (nreg >= 0x80860007) { | 1565 | if (nreg >= 0x80860007) { | |
1567 | tmx86_get_longrun_status(&frequency, | 1566 | tmx86_get_longrun_status(&frequency, | |
1568 | &voltage, &percentage); | 1567 | &voltage, &percentage); | |
1569 | aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", | 1568 | aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", | |
1570 | frequency, voltage, percentage); | 1569 | frequency, voltage, percentage); | |
1571 | } | 1570 | } | |
1572 | } | 1571 | } | |
1573 | 1572 | |||
1574 | static void | 1573 | static void | |
1575 | cpu_probe_base_features(struct cpu_info *ci, const char *cpuname) | 1574 | cpu_probe_base_features(struct cpu_info *ci, const char *cpuname) | |
1576 | { | 1575 | { | |
1577 | u_int descs[4]; | 1576 | u_int descs[4]; | |
1578 | int i; | 1577 | int i; | |
1579 | uint32_t brand[12]; | 1578 | uint32_t brand[12]; | |
1580 | 1579 | |||
1581 | memset(ci, 0, sizeof(*ci)); | 1580 | memset(ci, 0, sizeof(*ci)); | |
1582 | ci->ci_dev = cpuname; | 1581 | ci->ci_dev = cpuname; | |
1583 | 1582 | |||
1584 | ci->ci_cpu_type = x86_identify(); | 1583 | ci->ci_cpu_type = x86_identify(); | |
1585 | if (ci->ci_cpu_type >= 0) { | 1584 | if (ci->ci_cpu_type >= 0) { | |
1586 | /* Old pre-cpuid instruction cpu */ | 1585 | /* Old pre-cpuid instruction cpu */ | |
1587 | ci->ci_cpuid_level = -1; | 1586 | ci->ci_cpuid_level = -1; | |
1588 | return; | 1587 | return; | |
1589 | } | 1588 | } | |
1590 | 1589 | |||
1591 | /* | 1590 | /* | |
1592 | * This CPU supports cpuid instruction, so we can call x86_cpuid() | 1591 | * This CPU supports cpuid instruction, so we can call x86_cpuid() | |
1593 | * function. | 1592 | * function. | |
1594 | */ | 1593 | */ | |
1595 | 1594 | |||
1596 | /* | 1595 | /* | |
1597 | * Fn0000_0000: | 1596 | * Fn0000_0000: | |
1598 | * - Save cpuid max level. | 1597 | * - Save cpuid max level. | |
1599 | * - Save vendor string. | 1598 | * - Save vendor string. | |
1600 | */ | 1599 | */ | |
1601 | x86_cpuid(0, descs); | 1600 | x86_cpuid(0, descs); | |
1602 | ci->ci_cpuid_level = descs[0]; | 1601 | ci->ci_cpuid_level = descs[0]; | |
1603 | /* Save vendor string */ | 1602 | /* Save vendor string */ | |
1604 | ci->ci_vendor[0] = descs[1]; | 1603 | ci->ci_vendor[0] = descs[1]; | |
1605 | ci->ci_vendor[2] = descs[2]; | 1604 | ci->ci_vendor[2] = descs[2]; | |
1606 | ci->ci_vendor[1] = descs[3]; | 1605 | ci->ci_vendor[1] = descs[3]; | |
1607 | ci->ci_vendor[3] = 0; | 1606 | ci->ci_vendor[3] = 0; | |
1608 | 1607 | |||
1609 | /* | 1608 | /* | |
1610 | * Fn8000_0000: | 1609 | * Fn8000_0000: | |
1611 | * - Get cpuid extended function's max level. | 1610 | * - Get cpuid extended function's max level. | |
1612 | */ | 1611 | */ | |
1613 | x86_cpuid(0x80000000, descs); | 1612 | x86_cpuid(0x80000000, descs); | |
1614 | if (descs[0] >= 0x80000000) | 1613 | if (descs[0] >= 0x80000000) | |
1615 | ci->ci_cpuid_extlevel = descs[0]; | 1614 | ci->ci_cpuid_extlevel = descs[0]; | |
1616 | else { | 1615 | else { | |
1617 | /* Set lower value than 0x80000000 */ | 1616 | /* Set lower value than 0x80000000 */ | |
1618 | ci->ci_cpuid_extlevel = 0; | 1617 | ci->ci_cpuid_extlevel = 0; | |
1619 | } | 1618 | } | |
1620 | 1619 | |||
1621 | /* | 1620 | /* | |
1622 | * Fn8000_000[2-4]: | 1621 | * Fn8000_000[2-4]: | |
1623 | * - Save brand string. | 1622 | * - Save brand string. | |
1624 | */ | 1623 | */ | |
1625 | if (ci->ci_cpuid_extlevel >= 0x80000004) { | 1624 | if (ci->ci_cpuid_extlevel >= 0x80000004) { | |
1626 | x86_cpuid(0x80000002, brand); | 1625 | x86_cpuid(0x80000002, brand); | |
1627 | x86_cpuid(0x80000003, brand + 4); | 1626 | x86_cpuid(0x80000003, brand + 4); | |
1628 | x86_cpuid(0x80000004, brand + 8); | 1627 | x86_cpuid(0x80000004, brand + 8); | |
1629 | for (i = 0; i < 48; i++) | 1628 | for (i = 0; i < 48; i++) | |
1630 | if (((char *) brand)[i] != ' ') | 1629 | if (((char *) brand)[i] != ' ') | |
1631 | break; | 1630 | break; | |
1632 | memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); | 1631 | memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); | |
1633 | } | 1632 | } | |
1634 | 1633 | |||
1635 | if (ci->ci_cpuid_level < 1) | 1634 | if (ci->ci_cpuid_level < 1) | |
1636 | return; | 1635 | return; | |
1637 | 1636 | |||
1638 | /* | 1637 | /* | |
1639 | * Fn0000_0001: | 1638 | * Fn0000_0001: | |
1640 | * - Get CPU family, model and stepping (from eax). | 1639 | * - Get CPU family, model and stepping (from eax). | |
1641 | * - Initial local APIC ID and brand ID (from ebx) | 1640 | * - Initial local APIC ID and brand ID (from ebx) | |
1642 | * - CPUID2 (from ecx) | 1641 | * - CPUID2 (from ecx) | |
1643 | * - CPUID (from edx) | 1642 | * - CPUID (from edx) | |
1644 | */ | 1643 | */ | |
1645 | x86_cpuid(1, descs); | 1644 | x86_cpuid(1, descs); | |
1646 | ci->ci_signature = descs[0]; | 1645 | ci->ci_signature = descs[0]; | |
1647 | 1646 | |||
1648 | /* Extract full family/model values */ | 1647 | /* Extract full family/model values */ | |
1649 | ci->ci_family = CPUID_TO_FAMILY(ci->ci_signature); | 1648 | ci->ci_family = CPUID_TO_FAMILY(ci->ci_signature); | |
1650 | ci->ci_model = CPUID_TO_MODEL(ci->ci_signature); | 1649 | ci->ci_model = CPUID_TO_MODEL(ci->ci_signature); | |
1651 | 1650 | |||
1652 | /* Brand is low order 8 bits of ebx */ | 1651 | /* Brand is low order 8 bits of ebx */ | |
1653 | ci->ci_brand_id = __SHIFTOUT(descs[1], CPUID_BRAND_INDEX); | 1652 | ci->ci_brand_id = __SHIFTOUT(descs[1], CPUID_BRAND_INDEX); | |
1654 | /* Initial local APIC ID */ | 1653 | /* Initial local APIC ID */ | |
1655 | ci->ci_initapicid = __SHIFTOUT(descs[1], CPUID_LOCAL_APIC_ID); | 1654 | ci->ci_initapicid = __SHIFTOUT(descs[1], CPUID_LOCAL_APIC_ID); | |
1656 | 1655 | |||
1657 | ci->ci_feat_val[1] = descs[2]; | 1656 | ci->ci_feat_val[1] = descs[2]; | |
1658 | ci->ci_feat_val[0] = descs[3]; | 1657 | ci->ci_feat_val[0] = descs[3]; | |
1659 | 1658 | |||
1660 | if (ci->ci_cpuid_level < 3) | 1659 | if (ci->ci_cpuid_level < 3) | |
1661 | return; | 1660 | return; | |
1662 | 1661 | |||
1663 | /* | 1662 | /* | |
1664 | * If the processor serial number misfeature is present and supported, | 1663 | * If the processor serial number misfeature is present and supported, | |
1665 | * extract it here. | 1664 | * extract it here. | |
1666 | */ | 1665 | */ | |
1667 | if ((ci->ci_feat_val[0] & CPUID_PN) != 0) { | 1666 | if ((ci->ci_feat_val[0] & CPUID_PN) != 0) { | |
1668 | ci->ci_cpu_serial[0] = ci->ci_signature; | 1667 | ci->ci_cpu_serial[0] = ci->ci_signature; | |
1669 | x86_cpuid(3, descs); | 1668 | x86_cpuid(3, descs); | |
1670 | ci->ci_cpu_serial[2] = descs[2]; | 1669 | ci->ci_cpu_serial[2] = descs[2]; | |
1671 | ci->ci_cpu_serial[1] = descs[3]; | 1670 | ci->ci_cpu_serial[1] = descs[3]; | |
1672 | } | 1671 | } | |
1673 | 1672 | |||
1674 | if (ci->ci_cpuid_level < 0x7) | 1673 | if (ci->ci_cpuid_level < 0x7) | |
1675 | return; | 1674 | return; | |
1676 | 1675 | |||
1677 | x86_cpuid(7, descs); | 1676 | x86_cpuid(7, descs); | |
1678 | ci->ci_feat_val[5] = descs[1]; | 1677 | ci->ci_feat_val[5] = descs[1]; | |
1679 | ci->ci_feat_val[6] = descs[2]; | 1678 | ci->ci_feat_val[6] = descs[2]; | |
1680 | ci->ci_feat_val[7] = descs[3]; | 1679 | ci->ci_feat_val[7] = descs[3]; | |
1681 | 1680 | |||
1682 | if (ci->ci_cpuid_level < 0xd) | 1681 | if (ci->ci_cpuid_level < 0xd) | |
1683 | return; | 1682 | return; | |
1684 | 1683 | |||
1685 | /* Get support XCR0 bits */ | 1684 | /* Get support XCR0 bits */ | |
1686 | x86_cpuid2(0xd, 0, descs); | 1685 | x86_cpuid2(0xd, 0, descs); | |
1687 | ci->ci_feat_val[8] = descs[0]; /* Actually 64 bits */ | 1686 | ci->ci_feat_val[8] = descs[0]; /* Actually 64 bits */ | |
1688 | ci->ci_cur_xsave = descs[1]; | 1687 | ci->ci_cur_xsave = descs[1]; | |
1689 | ci->ci_max_xsave = descs[2]; | 1688 | ci->ci_max_xsave = descs[2]; | |
1690 | 1689 | |||
1691 | /* Additional flags (eg xsaveopt support) */ | 1690 | /* Additional flags (eg xsaveopt support) */ | |
1692 | x86_cpuid2(0xd, 1, descs); | 1691 | x86_cpuid2(0xd, 1, descs); | |
1693 | ci->ci_feat_val[9] = descs[0]; /* Actually 64 bits */ | 1692 | ci->ci_feat_val[9] = descs[0]; /* Actually 64 bits */ | |
1694 | } | 1693 | } | |
1695 | 1694 | |||
1696 | static void | 1695 | static void | |
1697 | cpu_probe_hv_features(struct cpu_info *ci, const char *cpuname) | 1696 | cpu_probe_hv_features(struct cpu_info *ci, const char *cpuname) | |
1698 | { | 1697 | { | |
1699 | uint32_t descs[4]; | 1698 | uint32_t descs[4]; | |
1700 | char hv_sig[13]; | 1699 | char hv_sig[13]; | |
1701 | char *p; | 1700 | char *p; | |
1702 | const char *hv_name; | 1701 | const char *hv_name; | |
1703 | int i; | 1702 | int i; | |
1704 | 1703 | |||
1705 | /* | 1704 | /* | |
1706 | * [RFC] CPUID usage for interaction between Hypervisors and Linux. | 1705 | * [RFC] CPUID usage for interaction between Hypervisors and Linux. | |
1707 | * http://lkml.org/lkml/2008/10/1/246 | 1706 | * http://lkml.org/lkml/2008/10/1/246 | |
1708 | * | 1707 | * | |
1709 | * KB1009458: Mechanisms to determine if software is running in | 1708 | * KB1009458: Mechanisms to determine if software is running in | |
1710 | * a VMware virtual machine | 1709 | * a VMware virtual machine | |
1711 | * http://kb.vmware.com/kb/1009458 | 1710 | * http://kb.vmware.com/kb/1009458 | |
1712 | */ | 1711 | */ | |
1713 | if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) { | 1712 | if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) { | |
1714 | x86_cpuid(0x40000000, descs); | 1713 | x86_cpuid(0x40000000, descs); | |
1715 | for (i = 1, p = hv_sig; i < 4; i++, p += sizeof(descs) / 4) | 1714 | for (i = 1, p = hv_sig; i < 4; i++, p += sizeof(descs) / 4) | |
1716 | memcpy(p, &descs[i], sizeof(descs[i])); | 1715 | memcpy(p, &descs[i], sizeof(descs[i])); | |
1717 | *p = '\0'; | 1716 | *p = '\0'; | |
1718 | /* | 1717 | /* | |
1719 | * HV vendor ID string | 1718 | * HV vendor ID string | |
1720 | * ------------+-------------- | 1719 | * ------------+-------------- | |
1721 | * HAXM "HAXMHAXMHAXM" | 1720 | * HAXM "HAXMHAXMHAXM" | |
1722 | * KVM "KVMKVMKVM" | 1721 | * KVM "KVMKVMKVM" | |
1723 | * Microsoft "Microsoft Hv" | 1722 | * Microsoft "Microsoft Hv" | |
1724 | * QEMU(TCG) "TCGTCGTCGTCG" | 1723 | * QEMU(TCG) "TCGTCGTCGTCG" | |
1725 | * VMware "VMwareVMware" | 1724 | * VMware "VMwareVMware" | |
1726 | * Xen "XenVMMXenVMM" | 1725 | * Xen "XenVMMXenVMM" | |
1727 | * NetBSD "___ NVMM ___" | 1726 | * NetBSD "___ NVMM ___" | |
1728 | */ | 1727 | */ | |
1729 | if (strncmp(hv_sig, "HAXMHAXMHAXM", 12) == 0) | 1728 | if (strncmp(hv_sig, "HAXMHAXMHAXM", 12) == 0) | |
1730 | hv_name = "HAXM"; | 1729 | hv_name = "HAXM"; | |
1731 | else if (strncmp(hv_sig, "KVMKVMKVM", 9) == 0) | 1730 | else if (strncmp(hv_sig, "KVMKVMKVM", 9) == 0) | |
1732 | hv_name = "KVM"; | 1731 | hv_name = "KVM"; | |
1733 | else if (strncmp(hv_sig, "Microsoft Hv", 12) == 0) | 1732 | else if (strncmp(hv_sig, "Microsoft Hv", 12) == 0) | |
1734 | hv_name = "Hyper-V"; | 1733 | hv_name = "Hyper-V"; | |
1735 | else if (strncmp(hv_sig, "TCGTCGTCGTCG", 12) == 0) | 1734 | else if (strncmp(hv_sig, "TCGTCGTCGTCG", 12) == 0) | |
1736 | hv_name = "QEMU(TCG)"; | 1735 | hv_name = "QEMU(TCG)"; | |
1737 | else if (strncmp(hv_sig, "VMwareVMware", 12) == 0) | 1736 | else if (strncmp(hv_sig, "VMwareVMware", 12) == 0) | |
1738 | hv_name = "VMware"; | 1737 | hv_name = "VMware"; | |
1739 | else if (strncmp(hv_sig, "XenVMMXenVMM", 12) == 0) | 1738 | else if (strncmp(hv_sig, "XenVMMXenVMM", 12) == 0) | |
1740 | hv_name = "Xen"; | 1739 | hv_name = "Xen"; | |
1741 | else if (strncmp(hv_sig, "___ NVMM ___", 12) == 0) | 1740 | else if (strncmp(hv_sig, "___ NVMM ___", 12) == 0) | |
1742 | hv_name = "NVMM"; | 1741 | hv_name = "NVMM"; | |
1743 | else | 1742 | else | |
1744 | hv_name = "unknown"; | 1743 | hv_name = "unknown"; | |
1745 | 1744 | |||
1746 | printf("%s: Running on hypervisor: %s\n", cpuname, hv_name); | 1745 | printf("%s: Running on hypervisor: %s\n", cpuname, hv_name); | |
1747 | } | 1746 | } | |
1748 | } | 1747 | } | |
1749 | 1748 | |||
1750 | static void | 1749 | static void | |
1751 | cpu_probe_features(struct cpu_info *ci) | 1750 | cpu_probe_features(struct cpu_info *ci) | |
1752 | { | 1751 | { | |
1753 | const struct cpu_cpuid_nameclass *cpup = NULL; | 1752 | const struct cpu_cpuid_nameclass *cpup = NULL; | |
1754 | unsigned int i; | 1753 | unsigned int i; | |
1755 | 1754 | |||
1756 | if (ci->ci_cpuid_level < 1) | 1755 | if (ci->ci_cpuid_level < 1) | |
1757 | return; | 1756 | return; | |
1758 | 1757 | |||
1759 | for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { | 1758 | for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { | |
1760 | if (!strncmp((char *)ci->ci_vendor, | 1759 | if (!strncmp((char *)ci->ci_vendor, | |
1761 | i386_cpuid_cpus[i].cpu_id, 12)) { | 1760 | i386_cpuid_cpus[i].cpu_id, 12)) { | |
1762 | cpup = &i386_cpuid_cpus[i]; | 1761 | cpup = &i386_cpuid_cpus[i]; | |
1763 | break; | 1762 | break; | |
1764 | } | 1763 | } | |
1765 | } | 1764 | } | |
1766 | 1765 | |||
1767 | if (cpup == NULL) | 1766 | if (cpup == NULL) | |
1768 | return; | 1767 | return; | |
1769 | 1768 | |||
1770 | i = ci->ci_family - CPU_MINFAMILY; | 1769 | i = ci->ci_family - CPU_MINFAMILY; | |
1771 | 1770 | |||
1772 | if (i >= __arraycount(cpup->cpu_family)) | 1771 | if (i >= __arraycount(cpup->cpu_family)) | |
1773 | i = __arraycount(cpup->cpu_family) - 1; | 1772 | i = __arraycount(cpup->cpu_family) - 1; | |
1774 | 1773 | |||
1775 | if (cpup->cpu_family[i].cpu_probe == NULL) | 1774 | if (cpup->cpu_family[i].cpu_probe == NULL) | |
1776 | return; | 1775 | return; | |
1777 | 1776 | |||
1778 | (*cpup->cpu_family[i].cpu_probe)(ci); | 1777 | (*cpup->cpu_family[i].cpu_probe)(ci); | |
1779 | } | 1778 | } | |
1780 | 1779 | |||
1781 | static void | 1780 | static void | |
1782 | print_bits(const char *cpuname, const char *hdr, const char *fmt, uint32_t val) | 1781 | print_bits(const char *cpuname, const char *hdr, const char *fmt, uint32_t val) | |
1783 | { | 1782 | { | |
1784 | char buf[32 * 16]; | 1783 | char buf[32 * 16]; | |
1785 | char *bp; | 1784 | char *bp; | |
1786 | 1785 | |||
1787 | #define MAX_LINE_LEN 79 /* get from command arg or 'stty cols' ? */ | 1786 | #define MAX_LINE_LEN 79 /* get from command arg or 'stty cols' ? */ | |
1788 | 1787 | |||
1789 | if (val == 0 || fmt == NULL) | 1788 | if (val == 0 || fmt == NULL) | |
1790 | return; | 1789 | return; | |
1791 | 1790 | |||
1792 | snprintb_m(buf, sizeof(buf), fmt, val, | 1791 | snprintb_m(buf, sizeof(buf), fmt, val, | |
1793 | MAX_LINE_LEN - strlen(cpuname) - 2 - strlen(hdr) - 1); | 1792 | MAX_LINE_LEN - strlen(cpuname) - 2 - strlen(hdr) - 1); | |
1794 | bp = buf; | 1793 | bp = buf; | |
1795 | while (*bp != '\0') { | 1794 | while (*bp != '\0') { | |
1796 | aprint_verbose("%s: %s %s\n", cpuname, hdr, bp); | 1795 | aprint_verbose("%s: %s %s\n", cpuname, hdr, bp); | |
1797 | bp += strlen(bp) + 1; | 1796 | bp += strlen(bp) + 1; | |
1798 | } | 1797 | } | |
1799 | } | 1798 | } | |
1800 | 1799 | |||
1801 | static void | 1800 | static void | |
1802 | dump_descs(uint32_t leafstart, uint32_t leafend, const char *cpuname, | 1801 | dump_descs(uint32_t leafstart, uint32_t leafend, const char *cpuname, | |
1803 | const char *blockname) | 1802 | const char *blockname) | |
1804 | { | 1803 | { | |
1805 | uint32_t descs[4]; | 1804 | uint32_t descs[4]; | |
1806 | uint32_t leaf; | 1805 | uint32_t leaf; | |
1807 | 1806 | |||
1808 | aprint_verbose("%s: highest %s info %08x\n", cpuname, blockname, | 1807 | aprint_verbose("%s: highest %s info %08x\n", cpuname, blockname, | |
1809 | leafend); | 1808 | leafend); | |
1810 | 1809 | |||
1811 | if (verbose) { | 1810 | if (verbose) { | |
1812 | for (leaf = leafstart; leaf <= leafend; leaf++) { | 1811 | for (leaf = leafstart; leaf <= leafend; leaf++) { | |
1813 | x86_cpuid(leaf, descs); | 1812 | x86_cpuid(leaf, descs); | |
1814 | printf("%s: %08x: %08x %08x %08x %08x\n", cpuname, | 1813 | printf("%s: %08x: %08x %08x %08x %08x\n", cpuname, | |
1815 | leaf, descs[0], descs[1], descs[2], descs[3]); | 1814 | leaf, descs[0], descs[1], descs[2], descs[3]); | |
1816 | } | 1815 | } | |
1817 | } | 1816 | } | |
1818 | } | 1817 | } | |
1819 | 1818 | |||
1820 | static void | 1819 | static void | |
1821 | identifycpu_cpuids_intel_0x04(struct cpu_info *ci) | 1820 | identifycpu_cpuids_intel_0x04(struct cpu_info *ci) | |
1822 | { | 1821 | { | |
1823 | u_int lp_max = 1; /* logical processors per package */ | 1822 | u_int lp_max = 1; /* logical processors per package */ | |
1824 | u_int smt_max; /* smt per core */ | 1823 | u_int smt_max; /* smt per core */ | |
1825 | u_int core_max = 1; /* core per package */ | 1824 | u_int core_max = 1; /* core per package */ | |
1826 | u_int smt_bits, core_bits; | 1825 | u_int smt_bits, core_bits; | |
1827 | uint32_t descs[4]; | 1826 | uint32_t descs[4]; | |
1828 | 1827 | |||
1829 | /* | 1828 | /* | |
1830 | * 253668.pdf 7.10.2 | 1829 | * 253668.pdf 7.10.2 | |
1831 | */ | 1830 | */ | |
1832 | 1831 | |||
1833 | if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { | 1832 | if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { | |
1834 | x86_cpuid(1, descs); | 1833 | x86_cpuid(1, descs); | |
1835 | lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES); | 1834 | lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES); | |
1836 | } | 1835 | } | |
1837 | x86_cpuid2(4, 0, descs); | 1836 | x86_cpuid2(4, 0, descs); | |
1838 | core_max = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG) + 1; | 1837 | core_max = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG) + 1; | |
1839 | 1838 | |||
1840 | assert(lp_max >= core_max); | 1839 | assert(lp_max >= core_max); | |
1841 | smt_max = lp_max / core_max; | 1840 | smt_max = lp_max / core_max; | |
1842 | smt_bits = ilog2(smt_max - 1) + 1; | 1841 | smt_bits = ilog2(smt_max - 1) + 1; | |
1843 | core_bits = ilog2(core_max - 1) + 1; | 1842 | core_bits = ilog2(core_max - 1) + 1; | |
1844 | 1843 | |||
1845 | if (smt_bits + core_bits) | 1844 | if (smt_bits + core_bits) | |
1846 | ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits); | 1845 | ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits); | |
1847 | 1846 | |||
1848 | if (core_bits) | 1847 | if (core_bits) | |
1849 | ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid, | 1848 | ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid, | |
1850 | __BITS(smt_bits, smt_bits + core_bits - 1)); | 1849 | __BITS(smt_bits, smt_bits + core_bits - 1)); | |
1851 | 1850 | |||
1852 | if (smt_bits) | 1851 | if (smt_bits) | |
1853 | ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, | 1852 | ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, | |
1854 | __BITS((int)0, (int)(smt_bits - 1))); | 1853 | __BITS((int)0, (int)(smt_bits - 1))); | |
1855 | } | 1854 | } | |
1856 | 1855 | |||
1857 | static void | 1856 | static void | |
1858 | identifycpu_cpuids_intel_0x0b(struct cpu_info *ci) | 1857 | identifycpu_cpuids_intel_0x0b(struct cpu_info *ci) | |
1859 | { | 1858 | { | |
1860 | const char *cpuname = ci->ci_dev; | 1859 | const char *cpuname = ci->ci_dev; | |
1861 | u_int smt_bits, core_bits, core_shift = 0, pkg_shift = 0; | 1860 | u_int smt_bits, core_bits, core_shift = 0, pkg_shift = 0; | |
1862 | uint32_t descs[4]; | 1861 | uint32_t descs[4]; | |
1863 | int i; | 1862 | int i; | |
1864 | 1863 | |||
1865 | x86_cpuid(0x0b, descs); | 1864 | x86_cpuid(0x0b, descs); | |
1866 | if (descs[1] == 0) { | 1865 | if (descs[1] == 0) { | |
1867 | identifycpu_cpuids_intel_0x04(ci); | 1866 | identifycpu_cpuids_intel_0x04(ci); | |
1868 | return; | 1867 | return; | |
1869 | } | 1868 | } | |
1870 | 1869 | |||
1871 | for (i = 0; ; i++) { | 1870 | for (i = 0; ; i++) { | |
1872 | unsigned int shiftnum, lvltype; | 1871 | unsigned int shiftnum, lvltype; | |
1873 | x86_cpuid2(0x0b, i, descs); | 1872 | x86_cpuid2(0x0b, i, descs); | |
1874 | 1873 | |||
1875 | /* On invalid level, (EAX and) EBX return 0 */ | 1874 | /* On invalid level, (EAX and) EBX return 0 */ | |
1876 | if (descs[1] == 0) | 1875 | if (descs[1] == 0) | |
1877 | break; | 1876 | break; | |
1878 | 1877 | |||
1879 | shiftnum = __SHIFTOUT(descs[0], CPUID_TOP_SHIFTNUM); | 1878 | shiftnum = __SHIFTOUT(descs[0], CPUID_TOP_SHIFTNUM); | |
1880 | lvltype = __SHIFTOUT(descs[2], CPUID_TOP_LVLTYPE); | 1879 | lvltype = __SHIFTOUT(descs[2], CPUID_TOP_LVLTYPE); | |
1881 | switch (lvltype) { | 1880 | switch (lvltype) { | |
1882 | case CPUID_TOP_LVLTYPE_SMT: | 1881 | case CPUID_TOP_LVLTYPE_SMT: | |
1883 | core_shift = shiftnum; | 1882 | core_shift = shiftnum; | |
1884 | break; | 1883 | break; | |
1885 | case CPUID_TOP_LVLTYPE_CORE: | 1884 | case CPUID_TOP_LVLTYPE_CORE: | |
1886 | pkg_shift = shiftnum; | 1885 | pkg_shift = shiftnum; | |
1887 | break; | 1886 | break; | |
1888 | case CPUID_TOP_LVLTYPE_INVAL: | 1887 | case CPUID_TOP_LVLTYPE_INVAL: | |
1889 | aprint_verbose("%s: Invalid level type\n", cpuname); | 1888 | aprint_verbose("%s: Invalid level type\n", cpuname); | |
1890 | break; | 1889 | break; | |
1891 | default: | 1890 | default: | |
1892 | aprint_verbose("%s: Unknown level type(%d) \n", | 1891 | aprint_verbose("%s: Unknown level type(%d) \n", | |
1893 | cpuname, lvltype); | 1892 | cpuname, lvltype); | |
1894 | break; | 1893 | break; | |
1895 | } | 1894 | } | |
1896 | } | 1895 | } | |
1897 | 1896 | |||
1898 | assert(pkg_shift >= core_shift); | 1897 | assert(pkg_shift >= core_shift); | |
1899 | smt_bits = core_shift; | 1898 | smt_bits = core_shift; | |
1900 | core_bits = pkg_shift - core_shift; | 1899 | core_bits = pkg_shift - core_shift; | |
1901 | 1900 | |||
1902 | ci->ci_packageid = ci->ci_initapicid >> pkg_shift; | 1901 | ci->ci_packageid = ci->ci_initapicid >> pkg_shift; | |
1903 | 1902 | |||
1904 | if (core_bits) | 1903 | if (core_bits) | |
1905 | ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid, | 1904 | ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid, | |
1906 | __BITS(core_shift, pkg_shift - 1)); | 1905 | __BITS(core_shift, pkg_shift - 1)); | |
1907 | 1906 | |||
1908 | if (smt_bits) | 1907 | if (smt_bits) | |
1909 | ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, | 1908 | ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, | |
1910 | __BITS((int)0, core_shift - 1)); | 1909 | __BITS((int)0, core_shift - 1)); | |
1911 | } | 1910 | } | |
1912 | 1911 | |||
1913 | static void | 1912 | static void | |
1914 | identifycpu_cpuids_intel(struct cpu_info *ci) | 1913 | identifycpu_cpuids_intel(struct cpu_info *ci) | |
1915 | { | 1914 | { | |
1916 | const char *cpuname = ci->ci_dev; | 1915 | const char *cpuname = ci->ci_dev; | |
1917 | 1916 | |||
1918 | if (ci->ci_cpuid_level >= 0x0b) | 1917 | if (ci->ci_cpuid_level >= 0x0b) | |
1919 | identifycpu_cpuids_intel_0x0b(ci); | 1918 | identifycpu_cpuids_intel_0x0b(ci); | |
1920 | else if (ci->ci_cpuid_level >= 4) | 1919 | else if (ci->ci_cpuid_level >= 4) | |
1921 | identifycpu_cpuids_intel_0x04(ci); | 1920 | identifycpu_cpuids_intel_0x04(ci); | |
1922 | 1921 | |||
1923 | aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, | 1922 | aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, | |
1924 | ci->ci_packageid); | 1923 | ci->ci_packageid); | |
1925 | aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); | 1924 | aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); | |
1926 | aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); | 1925 | aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); | |
1927 | } | 1926 | } | |
1928 | 1927 | |||
1929 | static void | 1928 | static void | |
1930 | identifycpu_cpuids_amd(struct cpu_info *ci) | 1929 | identifycpu_cpuids_amd(struct cpu_info *ci) | |
1931 | { | 1930 | { | |
1932 | const char *cpuname = ci->ci_dev; | 1931 | const char *cpuname = ci->ci_dev; | |
1933 | u_int lp_max, core_max; | 1932 | u_int lp_max, core_max; | |
1934 | int n, cpu_family, apic_id, smt_bits, core_bits = 0; | 1933 | int n, cpu_family, apic_id, smt_bits, core_bits = 0; | |
1935 | uint32_t descs[4]; | 1934 | uint32_t descs[4]; | |
1936 | 1935 | |||
1937 | apic_id = ci->ci_initapicid; | 1936 | apic_id = ci->ci_initapicid; | |
1938 | cpu_family = CPUID_TO_FAMILY(ci->ci_signature); | 1937 | cpu_family = CPUID_TO_FAMILY(ci->ci_signature); | |
1939 | 1938 | |||
1940 | if (cpu_family < 0xf) | 1939 | if (cpu_family < 0xf) | |
1941 | return; | 1940 | return; | |
1942 | 1941 | |||
1943 | if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { | 1942 | if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { | |
1944 | x86_cpuid(1, descs); | 1943 | x86_cpuid(1, descs); | |
1945 | lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES); | 1944 | lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES); | |
1946 | 1945 | |||
1947 | if (cpu_family >= 0x10 && ci->ci_max_ext_cpuid >= 0x8000008) { | 1946 | if (cpu_family >= 0x10 && ci->ci_cpuid_extlevel >= 0x8000008) { | |
1948 | x86_cpuid(0x8000008, descs); | 1947 | x86_cpuid(0x8000008, descs); | |
1949 | core_max = (descs[2] & 0xff) + 1; | 1948 | core_max = (descs[2] & 0xff) + 1; | |
1950 | n = (descs[2] >> 12) & 0x0f; | 1949 | n = (descs[2] >> 12) & 0x0f; | |
1951 | if (n != 0) | 1950 | if (n != 0) | |
1952 | core_bits = n; | 1951 | core_bits = n; | |
1953 | } | 1952 | } | |
1954 | } else { | 1953 | } else { | |
1955 | lp_max = 1; | 1954 | lp_max = 1; | |
1956 | } | 1955 | } | |
1957 | core_max = lp_max; | 1956 | core_max = lp_max; | |
1958 | 1957 | |||
1959 | smt_bits = ilog2((lp_max / core_max) - 1) + 1; | 1958 | smt_bits = ilog2((lp_max / core_max) - 1) + 1; | |
1960 | if (core_bits == 0) | 1959 | if (core_bits == 0) | |
1961 | core_bits = ilog2(core_max - 1) + 1; | 1960 | core_bits = ilog2(core_max - 1) + 1; | |
1962 | 1961 | |||
1963 | #if 0 /* MSRs need kernel mode */ | 1962 | #if 0 /* MSRs need kernel mode */ | |
1964 | if (cpu_family < 0x11) { | 1963 | if (cpu_family < 0x11) { | |
1965 | const uint64_t reg = rdmsr(MSR_NB_CFG); | 1964 | const uint64_t reg = rdmsr(MSR_NB_CFG); | |
1966 | if ((reg & NB_CFG_INITAPICCPUIDLO) == 0) { | 1965 | if ((reg & NB_CFG_INITAPICCPUIDLO) == 0) { | |
1967 | const u_int node_id = apic_id & __BITS(0, 2); | 1966 | const u_int node_id = apic_id & __BITS(0, 2); | |
1968 | apic_id = (cpu_family == 0xf) ? | 1967 | apic_id = (cpu_family == 0xf) ? | |
1969 | (apic_id >> core_bits) | (node_id << core_bits) : | 1968 | (apic_id >> core_bits) | (node_id << core_bits) : | |
1970 | (apic_id >> 5) | (node_id << 2); | 1969 | (apic_id >> 5) | (node_id << 2); | |
1971 | } | 1970 | } | |
1972 | } | 1971 | } | |
1973 | #endif | 1972 | #endif | |
1974 | 1973 | |||
1975 | if (cpu_family == 0x17) { | 1974 | if (cpu_family == 0x17) { | |
1976 | x86_cpuid(0x8000001e, descs); | 1975 | x86_cpuid(0x8000001e, descs); | |
1977 | const u_int threads = ((descs[1] >> 8) & 0xff) + 1; | 1976 | const u_int threads = ((descs[1] >> 8) & 0xff) + 1; | |
1978 | smt_bits = ilog2(threads); | 1977 | smt_bits = ilog2(threads); | |
1979 | core_bits -= smt_bits; | 1978 | core_bits -= smt_bits; | |
1980 | } | 1979 | } | |
1981 | 1980 | |||
1982 | if (smt_bits + core_bits) { | 1981 | if (smt_bits + core_bits) { | |
1983 | if (smt_bits + core_bits < 32) | 1982 | if (smt_bits + core_bits < 32) | |
1984 | ci->ci_packageid = 0; | 1983 | ci->ci_packageid = 0; | |
1985 | } | 1984 | } | |
1986 | if (core_bits) { | 1985 | if (core_bits) { | |
1987 | u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1); | 1986 | u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1); | |
1988 | ci->ci_coreid = __SHIFTOUT(apic_id, core_mask); | 1987 | ci->ci_coreid = __SHIFTOUT(apic_id, core_mask); | |
1989 | } | 1988 | } | |
1990 | if (smt_bits) { | 1989 | if (smt_bits) { | |
1991 | u_int smt_mask = __BITS(0, smt_bits - 1); | 1990 | u_int smt_mask = __BITS(0, smt_bits - 1); | |
1992 | ci->ci_smtid = __SHIFTOUT(apic_id, smt_mask); | 1991 | ci->ci_smtid = __SHIFTOUT(apic_id, smt_mask); | |
1993 | } | 1992 | } | |
1994 | 1993 | |||
1995 | aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, | 1994 | aprint_verbose("%s: Cluster/Package ID %u\n", cpuname, | |
1996 | ci->ci_packageid); | 1995 | ci->ci_packageid); | |
1997 | aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); | 1996 | aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid); | |
1998 | aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); | 1997 | aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid); | |
1999 | } | 1998 | } | |
2000 | 1999 | |||
2001 | static void | 2000 | static void | |
2002 | identifycpu_cpuids(struct cpu_info *ci) | 2001 | identifycpu_cpuids(struct cpu_info *ci) | |
2003 | { | 2002 | { | |
2004 | const char *cpuname = ci->ci_dev; | 2003 | const char *cpuname = ci->ci_dev; | |
2005 | 2004 | |||
2006 | aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid); | 2005 | aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid); | |
2007 | ci->ci_packageid = ci->ci_initapicid; | 2006 | ci->ci_packageid = ci->ci_initapicid; | |
2008 | ci->ci_coreid = 0; | 2007 | ci->ci_coreid = 0; | |
2009 | ci->ci_smtid = 0; | 2008 | ci->ci_smtid = 0; | |
2010 | 2009 | |||
2011 | if (cpu_vendor == CPUVENDOR_INTEL) | 2010 | if (cpu_vendor == CPUVENDOR_INTEL) | |
2012 | identifycpu_cpuids_intel(ci); | 2011 | identifycpu_cpuids_intel(ci); | |
2013 | else if (cpu_vendor == CPUVENDOR_AMD) | 2012 | else if (cpu_vendor == CPUVENDOR_AMD) | |
2014 | identifycpu_cpuids_amd(ci); | 2013 | identifycpu_cpuids_amd(ci); | |
2015 | } | 2014 | } | |
2016 | 2015 | |||
2017 | void | 2016 | void | |
2018 | identifycpu(int fd, const char *cpuname) | 2017 | identifycpu(int fd, const char *cpuname) | |
2019 | { | 2018 | { | |
2020 | const char *name = "", *modifier, *vendorname, *brand = ""; | 2019 | const char *name = "", *modifier, *vendorname, *brand = ""; | |
2021 | int class = CPUCLASS_386; | 2020 | int class = CPUCLASS_386; | |
2022 | unsigned int i; | 2021 | unsigned int i; | |
2023 | int modif, family; | 2022 | int modif, family; | |
2024 | const struct cpu_cpuid_nameclass *cpup = NULL; | 2023 | const struct cpu_cpuid_nameclass *cpup = NULL; | |
2025 | const struct cpu_cpuid_family *cpufam; | 2024 | const struct cpu_cpuid_family *cpufam; | |
2026 | struct cpu_info *ci, cistore; | 2025 | struct cpu_info *ci, cistore; | |
2027 | u_int descs[4]; | 2026 | u_int descs[4]; | |
2028 | size_t sz; | 2027 | size_t sz; | |
2029 | struct cpu_ucode_version ucode; | 2028 | struct cpu_ucode_version ucode; | |
2030 | union { | 2029 | union { | |
2031 | struct cpu_ucode_version_amd amd; | 2030 | struct cpu_ucode_version_amd amd; | |
2032 | struct cpu_ucode_version_intel1 intel1; | 2031 | struct cpu_ucode_version_intel1 intel1; | |
2033 | } ucvers; | 2032 | } ucvers; | |
2034 | 2033 | |||
2035 | ci = &cistore; | 2034 | ci = &cistore; | |
2036 | cpu_probe_base_features(ci, cpuname); | 2035 | cpu_probe_base_features(ci, cpuname); | |
2037 | dump_descs(0x00000000, ci->ci_cpuid_level, cpuname, "basic"); | 2036 | dump_descs(0x00000000, ci->ci_cpuid_level, cpuname, "basic"); | |
2038 | if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) { | 2037 | if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) { | |
2039 | x86_cpuid(0x40000000, descs); | 2038 | x86_cpuid(0x40000000, descs); | |
2040 | dump_descs(0x40000000, descs[0], cpuname, "hypervisor"); | 2039 | dump_descs(0x40000000, descs[0], cpuname, "hypervisor"); | |
2041 | } | 2040 | } | |
2042 | dump_descs(0x80000000, ci->ci_cpuid_extlevel, cpuname, "extended"); | 2041 | dump_descs(0x80000000, ci->ci_cpuid_extlevel, cpuname, "extended"); | |
2043 | 2042 | |||
2044 | cpu_probe_hv_features(ci, cpuname); | 2043 | cpu_probe_hv_features(ci, cpuname); | |
2045 | cpu_probe_features(ci); | 2044 | cpu_probe_features(ci); | |
2046 | 2045 | |||
2047 | if (ci->ci_cpu_type >= 0) { | 2046 | if (ci->ci_cpu_type >= 0) { | |
2048 | /* Old pre-cpuid instruction cpu */ | 2047 | /* Old pre-cpuid instruction cpu */ | |
2049 | if (ci->ci_cpu_type >= (int)__arraycount(i386_nocpuid_cpus)) | 2048 | if (ci->ci_cpu_type >= (int)__arraycount(i386_nocpuid_cpus)) | |
2050 | errx(1, "unknown cpu type %d", ci->ci_cpu_type); | 2049 | errx(1, "unknown cpu type %d", ci->ci_cpu_type); | |
2051 | name = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_name; | 2050 | name = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_name; | |
2052 | cpu_vendor = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendor; | 2051 | cpu_vendor = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendor; | |
2053 | vendorname = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendorname; | 2052 | vendorname = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendorname; | |
2054 | class = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_class; | 2053 | class = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_class; | |
2055 | ci->ci_info = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_info; | 2054 | ci->ci_info = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_info; | |
2056 | modifier = ""; | 2055 | modifier = ""; | |
2057 | } else { | 2056 | } else { | |
2058 | /* CPU which support cpuid instruction */ | 2057 | /* CPU which support cpuid instruction */ | |
2059 | modif = (ci->ci_signature >> 12) & 0x3; | 2058 | modif = (ci->ci_signature >> 12) & 0x3; | |
2060 | family = ci->ci_family; | 2059 | family = ci->ci_family; | |
2061 | if (family < CPU_MINFAMILY) | 2060 | if (family < CPU_MINFAMILY) | |
2062 | errx(1, "identifycpu: strange family value"); | 2061 | errx(1, "identifycpu: strange family value"); | |
2063 | if (family > CPU_MAXFAMILY) | 2062 | if (family > CPU_MAXFAMILY) | |
2064 | family = CPU_MAXFAMILY; | 2063 | family = CPU_MAXFAMILY; | |
2065 | 2064 | |||
2066 | for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { | 2065 | for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) { | |
2067 | if (!strncmp((char *)ci->ci_vendor, | 2066 | if (!strncmp((char *)ci->ci_vendor, | |
2068 | i386_cpuid_cpus[i].cpu_id, 12)) { | 2067 | i386_cpuid_cpus[i].cpu_id, 12)) { | |
2069 | cpup = &i386_cpuid_cpus[i]; | 2068 | cpup = &i386_cpuid_cpus[i]; | |
2070 | break; | 2069 | break; | |
2071 | } | 2070 | } | |
2072 | } | 2071 | } | |
2073 | 2072 | |||
2074 | if (cpup == NULL) { | 2073 | if (cpup == NULL) { | |
2075 | cpu_vendor = CPUVENDOR_UNKNOWN; | 2074 | cpu_vendor = CPUVENDOR_UNKNOWN; | |
2076 | if (ci->ci_vendor[0] != '\0') | 2075 | if (ci->ci_vendor[0] != '\0') | |
2077 | vendorname = (char *)&ci->ci_vendor[0]; | 2076 | vendorname = (char *)&ci->ci_vendor[0]; | |
2078 | else | 2077 | else | |
2079 | vendorname = "Unknown"; | 2078 | vendorname = "Unknown"; | |
2080 | class = family - 3; | 2079 | class = family - 3; | |
2081 | modifier = ""; | 2080 | modifier = ""; | |
2082 | name = ""; | 2081 | name = ""; | |
2083 | ci->ci_info = NULL; | 2082 | ci->ci_info = NULL; | |
2084 | } else { | 2083 | } else { | |
2085 | cpu_vendor = cpup->cpu_vendor; | 2084 | cpu_vendor = cpup->cpu_vendor; | |
2086 | vendorname = cpup->cpu_vendorname; | 2085 | vendorname = cpup->cpu_vendorname; | |
2087 | modifier = modifiers[modif]; | 2086 | modifier = modifiers[modif]; | |
2088 | cpufam = &cpup->cpu_family[family - CPU_MINFAMILY]; | 2087 | cpufam = &cpup->cpu_family[family - CPU_MINFAMILY]; | |
2089 | name = cpufam->cpu_models[ci->ci_model]; | 2088 | name = cpufam->cpu_models[ci->ci_model]; | |
2090 | if (name == NULL || *name == '\0') | 2089 | if (name == NULL || *name == '\0') | |
2091 | name = cpufam->cpu_model_default; | 2090 | name = cpufam->cpu_model_default; | |
2092 | class = cpufam->cpu_class; | 2091 | class = cpufam->cpu_class; | |
2093 | ci->ci_info = cpufam->cpu_info; | 2092 | ci->ci_info = cpufam->cpu_info; | |
2094 | 2093 | |||
2095 | if (cpu_vendor == CPUVENDOR_INTEL) { | 2094 | if (cpu_vendor == CPUVENDOR_INTEL) { | |
2096 | if (ci->ci_family == 6 && ci->ci_model >= 5) { | 2095 | if (ci->ci_family == 6 && ci->ci_model >= 5) { | |
2097 | const char *tmp; | 2096 | const char *tmp; | |
2098 | tmp = intel_family6_name(ci); | 2097 | tmp = intel_family6_name(ci); | |
2099 | if (tmp != NULL) | 2098 | if (tmp != NULL) | |
2100 | name = tmp; | 2099 | name = tmp; | |
2101 | } | 2100 | } | |
2102 | if (ci->ci_family == 15 && | 2101 | if (ci->ci_family == 15 && | |
2103 | ci->ci_brand_id < | 2102 | ci->ci_brand_id < | |
2104 | __arraycount(i386_intel_brand) && | 2103 | __arraycount(i386_intel_brand) && | |
2105 | i386_intel_brand[ci->ci_brand_id]) | 2104 | i386_intel_brand[ci->ci_brand_id]) | |
2106 | name = | 2105 | name = | |
2107 | i386_intel_brand[ci->ci_brand_id]; | 2106 | i386_intel_brand[ci->ci_brand_id]; | |
2108 | } | 2107 | } | |
2109 | 2108 | |||
2110 | if (cpu_vendor == CPUVENDOR_AMD) { | 2109 | if (cpu_vendor == CPUVENDOR_AMD) { | |
2111 | if (ci->ci_family == 6 && ci->ci_model >= 6) { | 2110 | if (ci->ci_family == 6 && ci->ci_model >= 6) { | |
2112 | if (ci->ci_brand_id == 1) | 2111 | if (ci->ci_brand_id == 1) | |
2113 | /* | 2112 | /* | |
2114 | * It's Duron. We override the | 2113 | * It's Duron. We override the | |
2115 | * name, since it might have | 2114 | * name, since it might have | |
2116 | * been misidentified as Athlon. | 2115 | * been misidentified as Athlon. | |
2117 | */ | 2116 | */ | |
2118 | name = | 2117 | name = | |
2119 | amd_brand[ci->ci_brand_id]; | 2118 | amd_brand[ci->ci_brand_id]; | |
2120 | else | 2119 | else | |
2121 | brand = amd_brand_name; | 2120 | brand = amd_brand_name; | |
2122 | } | 2121 | } | |
2123 | if (CPUID_TO_BASEFAMILY(ci->ci_signature) | 2122 | if (CPUID_TO_BASEFAMILY(ci->ci_signature) | |
2124 | == 0xf) { | 2123 | == 0xf) { | |
2125 | /* Identify AMD64 CPU names. */ | 2124 | /* Identify AMD64 CPU names. */ | |
2126 | const char *tmp; | 2125 | const char *tmp; | |
2127 | tmp = amd_amd64_name(ci); | 2126 | tmp = amd_amd64_name(ci); | |
2128 | if (tmp != NULL) | 2127 | if (tmp != NULL) | |
2129 | name = tmp; | 2128 | name = tmp; | |
2130 | } | 2129 | } | |
2131 | } | 2130 | } | |
2132 | 2131 | |||
2133 | if (cpu_vendor == CPUVENDOR_IDT && ci->ci_family >= 6) | 2132 | if (cpu_vendor == CPUVENDOR_IDT && ci->ci_family >= 6) | |
2134 | vendorname = "VIA"; | 2133 | vendorname = "VIA"; | |
2135 | } | 2134 | } | |
2136 | } | 2135 | } | |
2137 | 2136 | |||
2138 | ci->ci_cpu_class = class; | 2137 | ci->ci_cpu_class = class; | |
2139 | 2138 | |||
2140 | sz = sizeof(ci->ci_tsc_freq); | 2139 | sz = sizeof(ci->ci_tsc_freq); | |
2141 | (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0); | 2140 | (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0); | |
2142 | sz = sizeof(use_pae); | 2141 | sz = sizeof(use_pae); | |
2143 | (void)sysctlbyname("machdep.pae", &use_pae, &sz, NULL, 0); | 2142 | (void)sysctlbyname("machdep.pae", &use_pae, &sz, NULL, 0); | |
2144 | largepagesize = (use_pae ? 2 * 1024 * 1024 : 4 * 1024 * 1024); | 2143 | largepagesize = (use_pae ? 2 * 1024 * 1024 : 4 * 1024 * 1024); | |
2145 | 2144 | |||
2146 | /* | 2145 | /* | |
2147 | * The 'cpu_brand_string' is much more useful than the 'cpu_model' | 2146 | * The 'cpu_brand_string' is much more useful than the 'cpu_model' | |
2148 | * we try to determine from the family/model values. | 2147 | * we try to determine from the family/model values. | |
2149 | */ | 2148 | */ | |
2150 | if (*cpu_brand_string != '\0') | 2149 | if (*cpu_brand_string != '\0') | |
2151 | aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); | 2150 | aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); | |
2152 | 2151 | |||
2153 | aprint_normal("%s: %s", cpuname, vendorname); | 2152 | aprint_normal("%s: %s", cpuname, vendorname); | |
2154 | if (*modifier) | 2153 | if (*modifier) | |
2155 | aprint_normal(" %s", modifier); | 2154 | aprint_normal(" %s", modifier); | |
2156 | if (*name) | 2155 | if (*name) | |
2157 | aprint_normal(" %s", name); | 2156 | aprint_normal(" %s", name); | |
2158 | if (*brand) | 2157 | if (*brand) | |
2159 | aprint_normal(" %s", brand); | 2158 | aprint_normal(" %s", brand); | |
2160 | aprint_normal(" (%s-class)", classnames[class]); | 2159 | aprint_normal(" (%s-class)", classnames[class]); | |
2161 | 2160 | |||
2162 | if (ci->ci_tsc_freq != 0) | 2161 | if (ci->ci_tsc_freq != 0) | |
2163 | aprint_normal(", %ju.%02ju MHz", | 2162 | aprint_normal(", %ju.%02ju MHz", | |
2164 | ((uintmax_t)ci->ci_tsc_freq + 4999) / 1000000, | 2163 | ((uintmax_t)ci->ci_tsc_freq + 4999) / 1000000, | |
2165 | (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100); | 2164 | (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100); | |
2166 | aprint_normal("\n"); | 2165 | aprint_normal("\n"); | |
2167 | 2166 | |||
2168 | aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x", | 2167 | aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x", | |
2169 | ci->ci_family, ci->ci_model, CPUID_TO_STEPPING(ci->ci_signature)); | 2168 | ci->ci_family, ci->ci_model, CPUID_TO_STEPPING(ci->ci_signature)); | |
2170 | if (ci->ci_signature != 0) | 2169 | if (ci->ci_signature != 0) | |
2171 | aprint_normal(" (id %#x)", ci->ci_signature); | 2170 | aprint_normal(" (id %#x)", ci->ci_signature); | |
2172 | aprint_normal("\n"); | 2171 | aprint_normal("\n"); | |
2173 | 2172 | |||
2174 | if (ci->ci_info) | 2173 | if (ci->ci_info) | |
2175 | (*ci->ci_info)(ci); | 2174 | (*ci->ci_info)(ci); | |
2176 | 2175 | |||
2177 | /* | 2176 | /* | |
2178 | * display CPU feature flags | 2177 | * display CPU feature flags | |
2179 | */ | 2178 | */ | |
2180 | 2179 | |||
2181 | print_bits(cpuname, "features", CPUID_FLAGS1, ci->ci_feat_val[0]); | 2180 | print_bits(cpuname, "features", CPUID_FLAGS1, ci->ci_feat_val[0]); | |
2182 | print_bits(cpuname, "features1", CPUID2_FLAGS1, ci->ci_feat_val[1]); | 2181 | print_bits(cpuname, "features1", CPUID2_FLAGS1, ci->ci_feat_val[1]); | |
2183 | 2182 | |||
2184 | /* These next two are actually common definitions! */ | 2183 | /* These next two are actually common definitions! */ | |
2185 | print_bits(cpuname, "features2", | 2184 | print_bits(cpuname, "features2", | |
2186 | cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_EXT_FLAGS | 2185 | cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_EXT_FLAGS | |
2187 | : CPUID_EXT_FLAGS, ci->ci_feat_val[2]); | 2186 | : CPUID_EXT_FLAGS, ci->ci_feat_val[2]); | |
2188 | print_bits(cpuname, "features3", | 2187 | print_bits(cpuname, "features3", | |
2189 | cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_FLAGS4 | 2188 | cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_FLAGS4 | |
2190 | : CPUID_AMD_FLAGS4, ci->ci_feat_val[3]); | 2189 | : CPUID_AMD_FLAGS4, ci->ci_feat_val[3]); | |
2191 | 2190 | |||
2192 | print_bits(cpuname, "padloack features", CPUID_FLAGS_PADLOCK, | 2191 | print_bits(cpuname, "padloack features", CPUID_FLAGS_PADLOCK, | |
2193 | ci->ci_feat_val[4]); | 2192 | ci->ci_feat_val[4]); | |
2194 | if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | 2193 | if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | |
2195 | print_bits(cpuname, "features5", CPUID_SEF_FLAGS, | 2194 | print_bits(cpuname, "features5", CPUID_SEF_FLAGS, | |
2196 | ci->ci_feat_val[5]); | 2195 | ci->ci_feat_val[5]); | |
2197 | if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | 2196 | if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | |
2198 | print_bits(cpuname, "features6", CPUID_SEF_FLAGS1, | 2197 | print_bits(cpuname, "features6", CPUID_SEF_FLAGS1, | |
2199 | ci->ci_feat_val[6]); | 2198 | ci->ci_feat_val[6]); | |
2200 | 2199 | |||
2201 | if (cpu_vendor == CPUVENDOR_INTEL) | 2200 | if (cpu_vendor == CPUVENDOR_INTEL) | |
2202 | print_bits(cpuname, "features7", CPUID_SEF_FLAGS2, | 2201 | print_bits(cpuname, "features7", CPUID_SEF_FLAGS2, | |
2203 | ci->ci_feat_val[7]); | 2202 | ci->ci_feat_val[7]); | |
2204 | 2203 | |||
2205 | print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[8]); | 2204 | print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[8]); | |
2206 | print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS, | 2205 | print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS, | |
2207 | ci->ci_feat_val[9]); | 2206 | ci->ci_feat_val[9]); | |
2208 | 2207 | |||
2209 | if (ci->ci_max_xsave != 0) { | 2208 | if (ci->ci_max_xsave != 0) { | |
2210 | aprint_normal("%s: xsave area size: current %d, maximum %d", | 2209 | aprint_normal("%s: xsave area size: current %d, maximum %d", | |
2211 | cpuname, ci->ci_cur_xsave, ci->ci_max_xsave); | 2210 | cpuname, ci->ci_cur_xsave, ci->ci_max_xsave); | |
2212 | aprint_normal(", xgetbv %sabled\n", | 2211 | aprint_normal(", xgetbv %sabled\n", | |
2213 | ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis"); | 2212 | ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis"); | |
2214 | if (ci->ci_feat_val[1] & CPUID2_OSXSAVE) | 2213 | if (ci->ci_feat_val[1] & CPUID2_OSXSAVE) | |
2215 | print_bits(cpuname, "enabled xsave", XCR0_FLAGS1, | 2214 | print_bits(cpuname, "enabled xsave", XCR0_FLAGS1, | |
2216 | x86_xgetbv()); | 2215 | x86_xgetbv()); | |
2217 | } | 2216 | } | |
2218 | 2217 | |||
2219 | x86_print_cache_and_tlb_info(ci); | 2218 | x86_print_cache_and_tlb_info(ci); | |
2220 | 2219 | |||
2221 | if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) { | 2220 | if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) { | |
2222 | aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", | 2221 | aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", | |
2223 | cpuname, | 2222 | cpuname, | |
2224 | ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, | 2223 | ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, | |
2225 | ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, | 2224 | ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, | |
2226 | ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); | 2225 | ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); | |
2227 | } | 2226 | } | |
2228 | 2227 | |||
2229 | if (ci->ci_cpu_class == CPUCLASS_386) | 2228 | if (ci->ci_cpu_class == CPUCLASS_386) | |
2230 | errx(1, "NetBSD requires an 80486 or later processor"); | 2229 | errx(1, "NetBSD requires an 80486 or later processor"); | |
2231 | 2230 | |||
2232 | if (ci->ci_cpu_type == CPU_486DLC) { | 2231 | if (ci->ci_cpu_type == CPU_486DLC) { | |
2233 | #ifndef CYRIX_CACHE_WORKS | 2232 | #ifndef CYRIX_CACHE_WORKS | |
2234 | aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n"); | 2233 | aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n"); | |
2235 | #else | 2234 | #else | |
2236 | #ifndef CYRIX_CACHE_REALLY_WORKS | 2235 | #ifndef CYRIX_CACHE_REALLY_WORKS | |
2237 | aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n"); | 2236 | aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n"); | |
2238 | #else | 2237 | #else | |
2239 | aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n"); | 2238 | aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n"); | |
2240 | #endif | 2239 | #endif | |
2241 | #endif | 2240 | #endif | |
2242 | } | 2241 | } | |
2243 | 2242 | |||
2244 | /* | 2243 | /* | |
2245 | * Everything past this point requires a Pentium or later. | 2244 | * Everything past this point requires a Pentium or later. | |
2246 | */ | 2245 | */ | |
2247 | if (ci->ci_cpuid_level < 0) | 2246 | if (ci->ci_cpuid_level < 0) | |
2248 | return; | 2247 | return; | |
2249 | 2248 | |||
2250 | identifycpu_cpuids(ci); | 2249 | identifycpu_cpuids(ci); | |
2251 | 2250 | |||
2252 | if ((ci->ci_cpuid_level >= 5) | 2251 | if ((ci->ci_cpuid_level >= 5) | |
2253 | && ((cpu_vendor == CPUVENDOR_INTEL) | 2252 | && ((cpu_vendor == CPUVENDOR_INTEL) | |
2254 | || (cpu_vendor == CPUVENDOR_AMD))) { | 2253 | || (cpu_vendor == CPUVENDOR_AMD))) { | |
2255 | uint16_t lmin, lmax; | 2254 | uint16_t lmin, lmax; | |
2256 | x86_cpuid(5, descs); | 2255 | x86_cpuid(5, descs); | |
2257 | 2256 | |||
2258 | print_bits(cpuname, "MONITOR/MWAIT extensions", | 2257 | print_bits(cpuname, "MONITOR/MWAIT extensions", | |
2259 | CPUID_MON_FLAGS, descs[2]); | 2258 | CPUID_MON_FLAGS, descs[2]); | |
2260 | lmin = __SHIFTOUT(descs[0], CPUID_MON_MINSIZE); | 2259 | lmin = __SHIFTOUT(descs[0], CPUID_MON_MINSIZE); | |
2261 | lmax = __SHIFTOUT(descs[1], CPUID_MON_MAXSIZE); | 2260 | lmax = __SHIFTOUT(descs[1], CPUID_MON_MAXSIZE); | |
2262 | aprint_normal("%s: monitor-line size %hu", cpuname, lmin); | 2261 | aprint_normal("%s: monitor-line size %hu", cpuname, lmin); | |
2263 | if (lmin != lmax) | 2262 | if (lmin != lmax) | |
2264 | aprint_normal("-%hu", lmax); | 2263 | aprint_normal("-%hu", lmax); | |
2265 | aprint_normal("\n"); | 2264 | aprint_normal("\n"); | |
2266 | 2265 | |||
2267 | for (i = 0; i <= 7; i++) { | 2266 | for (i = 0; i <= 7; i++) { | |
2268 | unsigned int num = CPUID_MON_SUBSTATE(descs[3], i); | 2267 | unsigned int num = CPUID_MON_SUBSTATE(descs[3], i); | |
2269 | 2268 | |||
2270 | if (num != 0) | 2269 | if (num != 0) | |
2271 | aprint_normal("%s: C%u substates %u\n", | 2270 | aprint_normal("%s: C%u substates %u\n", | |
2272 | cpuname, i, num); | 2271 | cpuname, i, num); | |
2273 | } | 2272 | } | |
2274 | } | 2273 | } | |
2275 | if ((ci->ci_cpuid_level >= 6) | 2274 | if ((ci->ci_cpuid_level >= 6) | |
2276 | && ((cpu_vendor == CPUVENDOR_INTEL) | 2275 | && ((cpu_vendor == CPUVENDOR_INTEL) | |
2277 | || (cpu_vendor == CPUVENDOR_AMD))) { | 2276 | || (cpu_vendor == CPUVENDOR_AMD))) { | |
2278 | x86_cpuid(6, descs); | 2277 | x86_cpuid(6, descs); | |
2279 | print_bits(cpuname, "DSPM-eax", CPUID_DSPM_FLAGS, descs[0]); | 2278 | print_bits(cpuname, "DSPM-eax", CPUID_DSPM_FLAGS, descs[0]); | |
2280 | print_bits(cpuname, "DSPM-ecx", CPUID_DSPM_FLAGS1, descs[2]); | 2279 | print_bits(cpuname, "DSPM-ecx", CPUID_DSPM_FLAGS1, descs[2]); | |
2281 | } | 2280 | } | |
2282 | if ((ci->ci_cpuid_level >= 7) | 2281 | if ((ci->ci_cpuid_level >= 7) | |
2283 | && ((cpu_vendor == CPUVENDOR_INTEL) | 2282 | && ((cpu_vendor == CPUVENDOR_INTEL) | |
2284 | || (cpu_vendor == CPUVENDOR_AMD))) { | 2283 | || (cpu_vendor == CPUVENDOR_AMD))) { | |
2285 | x86_cpuid(7, descs); | 2284 | x86_cpuid(7, descs); | |
2286 | aprint_verbose("%s: SEF highest subleaf %08x\n", | 2285 | aprint_verbose("%s: SEF highest subleaf %08x\n", | |
2287 | cpuname, descs[0]); | 2286 | cpuname, descs[0]); | |
2288 | } | 2287 | } | |
2289 | 2288 | |||
2290 | if (cpu_vendor == CPUVENDOR_AMD) { | 2289 | if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) | |
2291 | x86_cpuid(0x80000000, descs); | 2290 | if (ci->ci_cpuid_extlevel >= 0x80000007) | |
2292 | if (descs[0] >= 0x80000000) | |||
2293 | ci->ci_max_ext_cpuid = descs[0]; | |||
2294 | else | |||
2295 | ci->ci_max_ext_cpuid = 0; | |||
2296 | if (ci->ci_max_ext_cpuid >= 0x80000007) | |||
2297 | powernow_probe(ci); | 2291 | powernow_probe(ci); | |
2298 | 2292 | |||
2299 | if (ci->ci_max_ext_cpuid >= 0x80000008) { | 2293 | if (cpu_vendor == CPUVENDOR_AMD) { | |
2294 | if (ci->ci_cpuid_extlevel >= 0x80000008) { | |||
2300 | x86_cpuid(0x80000008, descs); | 2295 | x86_cpuid(0x80000008, descs); | |
2301 | print_bits(cpuname, "AMD Extended features", | 2296 | print_bits(cpuname, "AMD Extended features", | |
2302 | CPUID_CAPEX_FLAGS, descs[1]); | 2297 | CPUID_CAPEX_FLAGS, descs[1]); | |
2303 | } | 2298 | } | |
2304 | 2299 | |||
2305 | if ((ci->ci_max_ext_cpuid >= 0x8000000a) | 2300 | if ((ci->ci_cpuid_extlevel >= 0x8000000a) | |
2306 | && (ci->ci_feat_val[3] & CPUID_SVM) != 0) { | 2301 | && (ci->ci_feat_val[3] & CPUID_SVM) != 0) { | |
2307 | x86_cpuid(0x8000000a, descs); | 2302 | x86_cpuid(0x8000000a, descs); | |
2308 | aprint_verbose("%s: SVM Rev. %d\n", cpuname, | 2303 | aprint_verbose("%s: SVM Rev. %d\n", cpuname, | |
2309 | descs[0] & 0xf); | 2304 | descs[0] & 0xf); | |
2310 | aprint_verbose("%s: SVM NASID %d\n", cpuname, | 2305 | aprint_verbose("%s: SVM NASID %d\n", cpuname, | |
2311 | descs[1]); | 2306 | descs[1]); | |
2312 | print_bits(cpuname, "SVM features", | 2307 | print_bits(cpuname, "SVM features", | |
2313 | CPUID_AMD_SVM_FLAGS, descs[3]); | 2308 | CPUID_AMD_SVM_FLAGS, descs[3]); | |
2314 | } | 2309 | } | |
2315 | if (ci->ci_max_ext_cpuid >= 0x8000001f) { | 2310 | if (ci->ci_cpuid_extlevel >= 0x8000001f) { | |
2316 | x86_cpuid(0x8000001f, descs); | 2311 | x86_cpuid(0x8000001f, descs); | |
2317 | print_bits(cpuname, "Encrypted Memory features", | 2312 | print_bits(cpuname, "Encrypted Memory features", | |
2318 | CPUID_AMD_ENCMEM_FLAGS, descs[0]); | 2313 | CPUID_AMD_ENCMEM_FLAGS, descs[0]); | |
2319 | } | 2314 | } | |
2320 | } else if (cpu_vendor == CPUVENDOR_INTEL) { | 2315 | } else if (cpu_vendor == CPUVENDOR_INTEL) { | |
2321 | int32_t bi_index; | 2316 | int32_t bi_index; | |
2322 | 2317 | |||
2323 | for (bi_index = 1; bi_index <= ci->ci_cpuid_level; bi_index++) { | 2318 | for (bi_index = 1; bi_index <= ci->ci_cpuid_level; bi_index++) { | |
2324 | x86_cpuid(bi_index, descs); | 2319 | x86_cpuid(bi_index, descs); | |
2325 | switch (bi_index) { | 2320 | switch (bi_index) { | |
2326 | case 0x0a: | 2321 | case 0x0a: | |
2327 | print_bits(cpuname, "Perfmon-eax", | 2322 | print_bits(cpuname, "Perfmon-eax", | |
2328 | CPUID_PERF_FLAGS0, descs[0]); | 2323 | CPUID_PERF_FLAGS0, descs[0]); | |
2329 | print_bits(cpuname, "Perfmon-ebx", | 2324 | print_bits(cpuname, "Perfmon-ebx", | |
2330 | CPUID_PERF_FLAGS1, descs[1]); | 2325 | CPUID_PERF_FLAGS1, descs[1]); | |
2331 | print_bits(cpuname, "Perfmon-edx", | 2326 | print_bits(cpuname, "Perfmon-edx", | |
2332 | CPUID_PERF_FLAGS3, descs[3]); | 2327 | CPUID_PERF_FLAGS3, descs[3]); | |
2333 | break; | 2328 | break; | |
2334 | default: | 2329 | default: | |
2335 | #if 0 | 2330 | #if 0 | |
2336 | aprint_verbose("%s: basic %08x-eax %08x\n", | 2331 | aprint_verbose("%s: basic %08x-eax %08x\n", | |
2337 | cpuname, bi_index, descs[0]); | 2332 | cpuname, bi_index, descs[0]); | |
2338 | aprint_verbose("%s: basic %08x-ebx %08x\n", | 2333 | aprint_verbose("%s: basic %08x-ebx %08x\n", | |
2339 | cpuname, bi_index, descs[1]); | 2334 | cpuname, bi_index, descs[1]); | |
2340 | aprint_verbose("%s: basic %08x-ecx %08x\n", | 2335 | aprint_verbose("%s: basic %08x-ecx %08x\n", | |
2341 | cpuname, bi_index, descs[2]); | 2336 | cpuname, bi_index, descs[2]); | |
2342 | aprint_verbose("%s: basic %08x-edx %08x\n", | 2337 | aprint_verbose("%s: basic %08x-edx %08x\n", | |
2343 | cpuname, bi_index, descs[3]); | 2338 | cpuname, bi_index, descs[3]); | |
2344 | #endif | 2339 | #endif | |
2345 | break; | 2340 | break; | |
2346 | } | 2341 | } | |
2347 | } | 2342 | } | |
2348 | } | 2343 | } | |
2349 | 2344 | |||
2350 | #ifdef INTEL_ONDEMAND_CLOCKMOD | 2345 | #ifdef INTEL_ONDEMAND_CLOCKMOD | |
2351 | clockmod_init(); | 2346 | clockmod_init(); | |
2352 | #endif | 2347 | #endif | |
2353 | 2348 | |||
2354 | if (cpu_vendor == CPUVENDOR_AMD) | 2349 | if (cpu_vendor == CPUVENDOR_AMD) | |
2355 | ucode.loader_version = CPU_UCODE_LOADER_AMD; | 2350 | ucode.loader_version = CPU_UCODE_LOADER_AMD; | |
2356 | else if (cpu_vendor == CPUVENDOR_INTEL) | 2351 | else if (cpu_vendor == CPUVENDOR_INTEL) | |
2357 | ucode.loader_version = CPU_UCODE_LOADER_INTEL1; | 2352 | ucode.loader_version = CPU_UCODE_LOADER_INTEL1; | |
2358 | else | 2353 | else | |
2359 | return; | 2354 | return; | |
2360 | 2355 | |||
2361 | ucode.data = &ucvers; | 2356 | ucode.data = &ucvers; | |
2362 | if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &ucode) < 0) { | 2357 | if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &ucode) < 0) { | |
2363 | #ifdef __i386__ | 2358 | #ifdef __i386__ | |
2364 | struct cpu_ucode_version_64 ucode_64; | 2359 | struct cpu_ucode_version_64 ucode_64; | |
2365 | if (errno != ENOTTY) | 2360 | if (errno != ENOTTY) | |
2366 | return; | 2361 | return; | |
2367 | /* Try the 64 bit ioctl */ | 2362 | /* Try the 64 bit ioctl */ | |
2368 | memset(&ucode_64, 0, sizeof ucode_64); | 2363 | memset(&ucode_64, 0, sizeof ucode_64); | |
2369 | ucode_64.data = &ucvers; | 2364 | ucode_64.data = &ucvers; | |
2370 | ucode_64.loader_version = ucode.loader_version; | 2365 | ucode_64.loader_version = ucode.loader_version; | |
2371 | if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION_64, &ucode_64) < 0) | 2366 | if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION_64, &ucode_64) < 0) | |
2372 | return; | 2367 | return; | |
2373 | #else | 2368 | #else | |
2374 | return; | 2369 | return; | |
2375 | #endif | 2370 | #endif | |
2376 | } | 2371 | } | |
2377 | 2372 | |||
2378 | if (cpu_vendor == CPUVENDOR_AMD) | 2373 | if (cpu_vendor == CPUVENDOR_AMD) | |
2379 | printf("%s: UCode version: 0x%"PRIx64"\n", cpuname, ucvers.amd.version); | 2374 | printf("%s: UCode version: 0x%"PRIx64"\n", cpuname, ucvers.amd.version); | |
2380 | else if (cpu_vendor == CPUVENDOR_INTEL) | 2375 | else if (cpu_vendor == CPUVENDOR_INTEL) | |
2381 | printf("%s: microcode version 0x%x, platform ID %d\n", cpuname, | 2376 | printf("%s: microcode version 0x%x, platform ID %d\n", cpuname, | |
2382 | ucvers.intel1.ucodeversion, ucvers.intel1.platformid); | 2377 | ucvers.intel1.ucodeversion, ucvers.intel1.platformid); | |
2383 | } | 2378 | } | |
2384 | 2379 | |||
2385 | static const struct x86_cache_info * | 2380 | static const struct x86_cache_info * | |
2386 | cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) | 2381 | cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc) | |
2387 | { | 2382 | { | |
2388 | int i; | 2383 | int i; | |
2389 | 2384 | |||
2390 | for (i = 0; cai[i].cai_desc != 0; i++) { | 2385 | for (i = 0; cai[i].cai_desc != 0; i++) { | |
2391 | if (cai[i].cai_desc == desc) | 2386 | if (cai[i].cai_desc == desc) | |
2392 | return (&cai[i]); | 2387 | return (&cai[i]); | |
2393 | } | 2388 | } | |
2394 | 2389 | |||
2395 | return (NULL); | 2390 | return (NULL); | |
2396 | } | 2391 | } | |
2397 | 2392 | |||
2398 | static const char * | 2393 | static const char * | |
2399 | print_cache_config(struct cpu_info *ci, int cache_tag, const char *name, | 2394 | print_cache_config(struct cpu_info *ci, int cache_tag, const char *name, | |
2400 | const char *sep) | 2395 | const char *sep) | |
2401 | { | 2396 | { | |
2402 | struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; | 2397 | struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; | |
2403 | char human_num[HUMAN_BUFSIZE]; | 2398 | char human_num[HUMAN_BUFSIZE]; | |
2404 | 2399 | |||
2405 | if (cai->cai_totalsize == 0) | 2400 | if (cai->cai_totalsize == 0) | |
2406 | return sep; | 2401 | return sep; | |
2407 | 2402 | |||
2408 | if (sep == NULL) | 2403 | if (sep == NULL) | |
2409 | aprint_verbose_dev(ci->ci_dev, ""); | 2404 | aprint_verbose_dev(ci->ci_dev, ""); | |
2410 | else | 2405 | else | |
2411 | aprint_verbose("%s", sep); | 2406 | aprint_verbose("%s", sep); | |
2412 | if (name != NULL) | 2407 | if (name != NULL) | |
2413 | aprint_verbose("%s ", name); | 2408 | aprint_verbose("%s ", name); | |
2414 | 2409 | |||
2415 | if (cai->cai_string != NULL) { | 2410 | if (cai->cai_string != NULL) { | |
2416 | aprint_verbose("%s ", cai->cai_string); | 2411 | aprint_verbose("%s ", cai->cai_string); | |
2417 | } else { | 2412 | } else { | |
2418 | (void)humanize_number(human_num, sizeof(human_num), | 2413 | (void)humanize_number(human_num, sizeof(human_num), | |
2419 | cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE); | 2414 | cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE); | |
2420 | aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize); | 2415 | aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize); | |
2421 | } | 2416 | } | |
2422 | switch (cai->cai_associativity) { | 2417 | switch (cai->cai_associativity) { | |
2423 | case 0: | 2418 | case 0: | |
2424 | aprint_verbose("disabled"); | 2419 | aprint_verbose("disabled"); | |
2425 | break; | 2420 | break; | |
2426 | case 1: | 2421 | case 1: | |
2427 | aprint_verbose("direct-mapped"); | 2422 | aprint_verbose("direct-mapped"); | |
2428 | break; | 2423 | break; | |
2429 | case 0xff: | 2424 | case 0xff: | |
2430 | aprint_verbose("fully associative"); | 2425 | aprint_verbose("fully associative"); | |
2431 | break; | 2426 | break; | |
2432 | default: | 2427 | default: | |
2433 | aprint_verbose("%d-way", cai->cai_associativity); | 2428 | aprint_verbose("%d-way", cai->cai_associativity); | |
2434 | break; | 2429 | break; | |
2435 | } | 2430 | } | |
2436 | return ", "; | 2431 | return ", "; | |
2437 | } | 2432 | } | |
2438 | 2433 | |||
2439 | static const char * | 2434 | static const char * | |
2440 | print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name, | 2435 | print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name, | |
2441 | const char *sep) | 2436 | const char *sep) | |
2442 | { | 2437 | { | |
2443 | struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; | 2438 | struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag]; | |
2444 | char human_num[HUMAN_BUFSIZE]; | 2439 | char human_num[HUMAN_BUFSIZE]; | |
2445 | 2440 | |||
2446 | if (cai->cai_totalsize == 0) | 2441 | if (cai->cai_totalsize == 0) | |
2447 | return sep; | 2442 | return sep; | |
2448 | 2443 | |||
2449 | if (sep == NULL) | 2444 | if (sep == NULL) | |
2450 | aprint_verbose_dev(ci->ci_dev, ""); | 2445 | aprint_verbose_dev(ci->ci_dev, ""); | |
2451 | else | 2446 | else | |
2452 | aprint_verbose("%s", sep); | 2447 | aprint_verbose("%s", sep); | |
2453 | if (name != NULL) | 2448 | if (name != NULL) | |
2454 | aprint_verbose("%s ", name); | 2449 | aprint_verbose("%s ", name); | |
2455 | 2450 | |||
2456 | if (cai->cai_string != NULL) { | 2451 | if (cai->cai_string != NULL) { | |
2457 | aprint_verbose("%s", cai->cai_string); | 2452 | aprint_verbose("%s", cai->cai_string); | |
2458 | } else { | 2453 | } else { | |
2459 | (void)humanize_number(human_num, sizeof(human_num), | 2454 | (void)humanize_number(human_num, sizeof(human_num), | |
2460 | cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE); | 2455 | cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE); | |
2461 | aprint_verbose("%d %s entries ", cai->cai_totalsize, | 2456 | aprint_verbose("%d %s entries ", cai->cai_totalsize, | |
2462 | human_num); | 2457 | human_num); | |
2463 | switch (cai->cai_associativity) { | 2458 | switch (cai->cai_associativity) { | |
2464 | case 0: | 2459 | case 0: | |
2465 | aprint_verbose("disabled"); | 2460 | aprint_verbose("disabled"); | |
2466 | break; | 2461 | break; | |
2467 | case 1: | 2462 | case 1: | |
2468 | aprint_verbose("direct-mapped"); | 2463 | aprint_verbose("direct-mapped"); | |
2469 | break; | 2464 | break; | |
2470 | case 0xff: | 2465 | case 0xff: | |
2471 | aprint_verbose("fully associative"); | 2466 | aprint_verbose("fully associative"); | |
2472 | break; | 2467 | break; | |
2473 | default: | 2468 | default: | |
2474 | aprint_verbose("%d-way", cai->cai_associativity); | 2469 | aprint_verbose("%d-way", cai->cai_associativity); | |
2475 | break; | 2470 | break; | |
2476 | } | 2471 | } | |
2477 | } | 2472 | } | |
2478 | return ", "; | 2473 | return ", "; | |
2479 | } | 2474 | } | |
2480 | 2475 | |||
2481 | static void | 2476 | static void | |
2482 | x86_print_cache_and_tlb_info(struct cpu_info *ci) | 2477 | x86_print_cache_and_tlb_info(struct cpu_info *ci) | |
2483 | { | 2478 | { | |
2484 | const char *sep = NULL; | 2479 | const char *sep = NULL; | |
2485 | 2480 | |||
2486 | if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 || | 2481 | if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 || | |
2487 | ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) { | 2482 | ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) { | |
2488 | sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL); | 2483 | sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL); | |
2489 | sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep); | 2484 | sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep); | |
2490 | if (sep != NULL) | 2485 | if (sep != NULL) | |
2491 | aprint_verbose("\n"); | 2486 | aprint_verbose("\n"); | |
2492 | } | 2487 | } | |
2493 | if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) { | 2488 | if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) { | |
2494 | sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL); | 2489 | sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL); | |
2495 | if (sep != NULL) | 2490 | if (sep != NULL) | |
2496 | aprint_verbose("\n"); | 2491 | aprint_verbose("\n"); | |
2497 | } | 2492 | } | |
2498 | if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { | 2493 | if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { | |
2499 | sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); | 2494 | sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); | |
2500 | if (sep != NULL) | 2495 | if (sep != NULL) | |
2501 | aprint_verbose("\n"); | 2496 | aprint_verbose("\n"); | |
2502 | } | 2497 | } | |
2503 | if (ci->ci_cinfo[CAI_PREFETCH].cai_linesize != 0) { | 2498 | if (ci->ci_cinfo[CAI_PREFETCH].cai_linesize != 0) { | |
2504 | aprint_verbose_dev(ci->ci_dev, "%dB prefetching", | 2499 | aprint_verbose_dev(ci->ci_dev, "%dB prefetching", | |
2505 | ci->ci_cinfo[CAI_PREFETCH].cai_linesize); | 2500 | ci->ci_cinfo[CAI_PREFETCH].cai_linesize); | |
2506 | if (sep != NULL) | 2501 | if (sep != NULL) | |
2507 | aprint_verbose("\n"); | 2502 | aprint_verbose("\n"); | |
2508 | } | 2503 | } | |
2509 | if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) { | 2504 | if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) { | |
2510 | sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL); | 2505 | sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL); | |
2511 | sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep); | 2506 | sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep); | |
2512 | if (sep != NULL) | 2507 | if (sep != NULL) | |
2513 | aprint_verbose("\n"); | 2508 | aprint_verbose("\n"); | |
2514 | } | 2509 | } | |
2515 | if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) { | 2510 | if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) { | |
2516 | sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL); | 2511 | sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL); | |
2517 | sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep); | 2512 | sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep); | |
2518 | if (sep != NULL) | 2513 | if (sep != NULL) | |
2519 | aprint_verbose("\n"); | 2514 | aprint_verbose("\n"); | |
2520 | } | 2515 | } | |
2521 | if (ci->ci_cinfo[CAI_L2_ITLB].cai_totalsize != 0) { | 2516 | if (ci->ci_cinfo[CAI_L2_ITLB].cai_totalsize != 0) { | |
2522 | sep = print_tlb_config(ci, CAI_L2_ITLB, "L2 ITLB", NULL); | 2517 | sep = print_tlb_config(ci, CAI_L2_ITLB, "L2 ITLB", NULL); | |
2523 | sep = print_tlb_config(ci, CAI_L2_ITLB2, NULL, sep); | 2518 | sep = print_tlb_config(ci, CAI_L2_ITLB2, NULL, sep); | |
2524 | if (sep != NULL) | 2519 | if (sep != NULL) | |
2525 | aprint_verbose("\n"); | 2520 | aprint_verbose("\n"); | |
2526 | } | 2521 | } | |
2527 | if (ci->ci_cinfo[CAI_L2_DTLB].cai_totalsize != 0) { | 2522 | if (ci->ci_cinfo[CAI_L2_DTLB].cai_totalsize != 0) { | |
2528 | sep = print_tlb_config(ci, CAI_L2_DTLB, "L2 DTLB", NULL); | 2523 | sep = print_tlb_config(ci, CAI_L2_DTLB, "L2 DTLB", NULL); | |
2529 | sep = print_tlb_config(ci, CAI_L2_DTLB2, NULL, sep); | 2524 | sep = print_tlb_config(ci, CAI_L2_DTLB2, NULL, sep); | |
2530 | if (sep != NULL) | 2525 | if (sep != NULL) | |
2531 | aprint_verbose("\n"); | 2526 | aprint_verbose("\n"); | |
2532 | } | 2527 | } | |
2533 | if (ci->ci_cinfo[CAI_L2_STLB].cai_totalsize != 0) { | 2528 | if (ci->ci_cinfo[CAI_L2_STLB].cai_totalsize != 0) { | |
2534 | sep = print_tlb_config(ci, CAI_L2_STLB, "L2 STLB", NULL); | 2529 | sep = print_tlb_config(ci, CAI_L2_STLB, "L2 STLB", NULL); | |
2535 | sep = print_tlb_config(ci, CAI_L2_STLB2, NULL, sep); | 2530 | sep = print_tlb_config(ci, CAI_L2_STLB2, NULL, sep); | |
2536 | sep = print_tlb_config(ci, CAI_L2_STLB3, NULL, sep); | 2531 | sep = print_tlb_config(ci, CAI_L2_STLB3, NULL, sep); | |
2537 | if (sep != NULL) | 2532 | if (sep != NULL) | |
2538 | aprint_verbose("\n"); | 2533 | aprint_verbose("\n"); | |
2539 | } | 2534 | } | |
2540 | if (ci->ci_cinfo[CAI_L1_1GBITLB].cai_totalsize != 0) { | 2535 | if (ci->ci_cinfo[CAI_L1_1GBITLB].cai_totalsize != 0) { | |
2541 | sep = print_tlb_config(ci, CAI_L1_1GBITLB, "L1 1GB page ITLB", | 2536 | sep = print_tlb_config(ci, CAI_L1_1GBITLB, "L1 1GB page ITLB", | |
2542 | NULL); | 2537 | NULL); | |
2543 | if (sep != NULL) | 2538 | if (sep != NULL) | |
2544 | aprint_verbose("\n"); | 2539 | aprint_verbose("\n"); | |
2545 | } | 2540 | } | |
2546 | if (ci->ci_cinfo[CAI_L1_1GBDTLB].cai_totalsize != 0) { | 2541 | if (ci->ci_cinfo[CAI_L1_1GBDTLB].cai_totalsize != 0) { | |
2547 | sep = print_tlb_config(ci, CAI_L1_1GBDTLB, "L1 1GB page DTLB", | 2542 | sep = print_tlb_config(ci, CAI_L1_1GBDTLB, "L1 1GB page DTLB", | |
2548 | NULL); | 2543 | NULL); | |
2549 | if (sep != NULL) | 2544 | if (sep != NULL) | |
2550 | aprint_verbose("\n"); | 2545 | aprint_verbose("\n"); | |
2551 | } | 2546 | } | |
2552 | if (ci->ci_cinfo[CAI_L2_1GBITLB].cai_totalsize != 0) { | 2547 | if (ci->ci_cinfo[CAI_L2_1GBITLB].cai_totalsize != 0) { | |
2553 | sep = print_tlb_config(ci, CAI_L2_1GBITLB, "L2 1GB page ITLB", | 2548 | sep = print_tlb_config(ci, CAI_L2_1GBITLB, "L2 1GB page ITLB", | |
2554 | NULL); | 2549 | NULL); | |
2555 | if (sep != NULL) | 2550 | if (sep != NULL) | |
2556 | aprint_verbose("\n"); | 2551 | aprint_verbose("\n"); | |
2557 | } | 2552 | } | |
2558 | if (ci->ci_cinfo[CAI_L2_1GBDTLB].cai_totalsize != 0) { | 2553 | if (ci->ci_cinfo[CAI_L2_1GBDTLB].cai_totalsize != 0) { | |
2559 | sep = print_tlb_config(ci, CAI_L2_1GBDTLB, "L2 1GB page DTLB", | 2554 | sep = print_tlb_config(ci, CAI_L2_1GBDTLB, "L2 1GB page DTLB", | |
2560 | NULL); | 2555 | NULL); | |
2561 | if (sep != NULL) | 2556 | if (sep != NULL) | |
2562 | aprint_verbose("\n"); | 2557 | aprint_verbose("\n"); | |
2563 | } | 2558 | } | |
2564 | } | 2559 | } | |
2565 | 2560 | |||
2566 | static void | 2561 | static void | |
2567 | powernow_probe(struct cpu_info *ci) | 2562 | powernow_probe(struct cpu_info *ci) | |
2568 | { | 2563 | { | |
2569 | uint32_t regs[4]; | 2564 | uint32_t regs[4]; | |
2570 | char buf[256]; | 2565 | char buf[256]; | |
2571 | 2566 | |||
2572 | x86_cpuid(0x80000007, regs); | 2567 | x86_cpuid(0x80000007, regs); | |
2573 | 2568 | |||
2574 | snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]); | 2569 | snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]); | |
2575 | aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n", | 2570 | aprint_normal_dev(ci->ci_dev, "Power Management features: %s\n", buf); | |
2576 | buf); | |||
2577 | } | 2571 | } | |
2578 | 2572 | |||
2579 | bool | 2573 | bool | |
2580 | identifycpu_bind(void) | 2574 | identifycpu_bind(void) | |
2581 | { | 2575 | { | |
2582 | 2576 | |||
2583 | return true; | 2577 | return true; | |
2584 | } | 2578 | } | |
2585 | 2579 | |||
2586 | int | 2580 | int | |
2587 | ucodeupdate_check(int fd, struct cpu_ucode *uc) | 2581 | ucodeupdate_check(int fd, struct cpu_ucode *uc) | |
2588 | { | 2582 | { | |
2589 | struct cpu_info ci; | 2583 | struct cpu_info ci; | |
2590 | int loader_version, res; | 2584 | int loader_version, res; | |
2591 | struct cpu_ucode_version versreq; | 2585 | struct cpu_ucode_version versreq; | |
2592 | 2586 | |||
2593 | cpu_probe_base_features(&ci, "unknown"); | 2587 | cpu_probe_base_features(&ci, "unknown"); | |
2594 | 2588 | |||
2595 | if (!strcmp((char *)ci.ci_vendor, "AuthenticAMD")) | 2589 | if (!strcmp((char *)ci.ci_vendor, "AuthenticAMD")) | |
2596 | loader_version = CPU_UCODE_LOADER_AMD; | 2590 | loader_version = CPU_UCODE_LOADER_AMD; | |
2597 | else if (!strcmp((char *)ci.ci_vendor, "GenuineIntel")) | 2591 | else if (!strcmp((char *)ci.ci_vendor, "GenuineIntel")) | |
2598 | loader_version = CPU_UCODE_LOADER_INTEL1; | 2592 | loader_version = CPU_UCODE_LOADER_INTEL1; | |
2599 | else | 2593 | else | |
2600 | return -1; | 2594 | return -1; | |
2601 | 2595 | |||
2602 | /* check whether the kernel understands this loader version */ | 2596 | /* check whether the kernel understands this loader version */ | |
2603 | versreq.loader_version = loader_version; | 2597 | versreq.loader_version = loader_version; | |
2604 | versreq.data = 0; | 2598 | versreq.data = 0; | |
2605 | res = ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &versreq); | 2599 | res = ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &versreq); | |
2606 | if (res) | 2600 | if (res) | |
2607 | return -1; | 2601 | return -1; | |
2608 | 2602 | |||
2609 | switch (loader_version) { | 2603 | switch (loader_version) { | |
2610 | case CPU_UCODE_LOADER_AMD: | 2604 | case CPU_UCODE_LOADER_AMD: | |
2611 | if (uc->cpu_nr != -1) { | 2605 | if (uc->cpu_nr != -1) { | |
2612 | /* printf? */ | 2606 | /* printf? */ | |
2613 | return -1; | 2607 | return -1; | |
2614 | } | 2608 | } | |
2615 | uc->cpu_nr = CPU_UCODE_ALL_CPUS; | 2609 | uc->cpu_nr = CPU_UCODE_ALL_CPUS; | |
2616 | break; | 2610 | break; | |
2617 | case CPU_UCODE_LOADER_INTEL1: | 2611 | case CPU_UCODE_LOADER_INTEL1: | |
2618 | if (uc->cpu_nr == -1) | 2612 | if (uc->cpu_nr == -1) | |
2619 | uc->cpu_nr = CPU_UCODE_ALL_CPUS; /* for Xen */ | 2613 | uc->cpu_nr = CPU_UCODE_ALL_CPUS; /* for Xen */ | |
2620 | else | 2614 | else | |
2621 | uc->cpu_nr = CPU_UCODE_CURRENT_CPU; | 2615 | uc->cpu_nr = CPU_UCODE_CURRENT_CPU; | |
2622 | break; | 2616 | break; | |
2623 | default: /* can't happen */ | 2617 | default: /* can't happen */ | |
2624 | return -1; | 2618 | return -1; | |
2625 | } | 2619 | } | |
2626 | uc->loader_version = loader_version; | 2620 | uc->loader_version = loader_version; | |
2627 | return 0; | 2621 | return 0; | |
2628 | } | 2622 | } |