1 /++
2 $(H2 AMD CPUID Information)
3 
4 $(GREEN This module is compatible with betterC compilation mode.)
5 
6 References:
7     AMD CPUID Specification. Publication # 25481 / Revision: 2.34 / Issue Date: September 2010
8 
9 License:   $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
10 
11 Authors:   Ilya Yaroshenko
12 +/
13 module cpuid.amd;
14 
15 version(X86)
16     version = X86_Any;
17 else
18 version(X86_64)
19     version = X86_Any;
20 
21 version(X86_Any):
22 
23 public import cpuid.x86_any;
24 
25 /++
26 L1 Cache and TLB Identifiers.
27 
28 The associativity fields are encoded as follows:
29  
30 Specification: AMD
31 +/
32 union LeafExt5Information
33 {
34     version(BigEndian) static assert(0, "Leaf2Information is not implemented for BigEndian architecture.");
35 
36     ///
37     CpuInfo info;
38 
39     ///
40     struct
41     {
42         /// Instruction TLB number of entries for 2 MB and 4 MB pages.
43         ubyte L1ITlb2and4MSize;
44         /// Instruction TLB associativity for 2 MB and 4 MB pages.
45         ubyte L1ITlb2and4MAssoc;
46         /// Data TLB number of entries for 2 MB and 4 MB pages.
47         ubyte L1DTlb2and4MSize;
48         /// Data TLB associativity for 2 MB and 4 MB pages.
49         ubyte L1DTlb2and4MAssoc;
50 
51         /// Instruction TLB number of entries for 4 KB pages.
52         ubyte L1ITlb4KSize;
53         /// Instruction TLB associativity for 4 KB pages.
54         /// See_also: CPUID Fn8000_0005_EDX[L1IcAssoc].
55         ubyte L1ITlb4KAssoc;
56         /// Data TLB number of entries for 4 KB pages.
57         ubyte L1DTlb4KSize;
58         /// Data TLB associativity for 4 KB pages.
59         /// See_also: CPUID Fn8000_0005_EDX[L1IcAssoc].
60         ubyte L1DTlb4KAssoc;
61 
62         /// L1 data cache line size in bytes.
63         ubyte L1DcLineSize;
64         /// L1 data cache lines per tag.
65         ubyte L1DcLinesPerTag;
66         /// L1 data cache associativity.
67         /// See_also: CPUID Fn8000_0005_EDX[L1IcAssoc].
68         ubyte L1DcAssoc;
69         /// L1 data cache size in KB.
70         ubyte L1DcSize;
71 
72         /// L1 instruction cache line size in bytes.
73         ubyte L1IcLineSize;
74         /// L1 instruction cache lines per tag.
75         ubyte L1IcLinesPerTag;
76         /// L1 instruction cache associativity.
77         ubyte L1IcAssoc;
78         /// L1 instruction cache size KB.
79         ubyte L1IcSize;
80     }
81 }
82 
83 /++
84 L2/L3 Cache and TLB Identifiers.
85 
86 This function contains the processor’s second level cache and TLB characteristics for each core.
87 The EDX register contains the processor’s third level cache characteristics that are shared by all cores of the processor.
88 
89 Note:
90     Use $(MREF decodeL2orL3Assoc) to get final result for any `*Assoc` field.
91 
92 Specification: AMD
93 +/
94 union LeafExt6Information
95 {
96     /// CPUID payload
97     CpuInfo info;
98 
99     ///
100     struct
101     {
102         import mir.bitmanip: bitfields;
103 
104         version(D_Ddoc)
105         {
106             const @trusted @property pure nothrow @nogc:
107             /// L2 instruction TLB number of entries for 4 KB pages.
108             uint L2ITlb4KSize();
109             /// L2 instruction TLB associativity for 4 KB pages.
110             uint L2ITlb4KAssoc();
111             /// L2 data TLB number of entries for 4 KB pages.
112             uint L2DTlb4KSize();
113             /// L2 data TLB associativity for 4 KB pages.
114             uint L2DTlb4KAssoc();
115             /// L2 instruction TLB number of entries for 2 MB and 4 MB pages.
116             /// The value returned is for the number of entries available for the 2 MB page size; 4 MB pages require two 2 MB entries, so the number of entries available for the 4 MB page size is one-half the returned value.
117             uint L2ITlb2and4MSize();
118             /// L2 instruction TLB associativity for 2 MB and 4 MB pages.
119             uint L2ITlb2and4MAssoc();
120             /// L2 data TLB number of entries for 2 MB and 4 MB pages.
121             /// The value returned is for the number of entries available for the 2 MB page size; 4 MB pages require two 2 MB entries, so the number of entries available for the 4 MB page size is one-half the returned value.
122             uint L2DTlb2and4MSize();
123             /// L2 data TLB associativity for 2 MB and 4 MB pages.
124             uint L2DTlb2and4MAssoc();
125             /// L2 cache line size in bytes.
126             uint L2LineSize();
127             /// L2 cache lines per tag.
128             uint L2LinesPerTag();
129             /// L2 cache associativity.
130             uint L2Assoc();
131             /// L2 cache size in KB.
132             uint L2Size();
133             /// L3 cache line size in bytes. 
134             uint L3LineSize();
135             /// L3 cache lines per tag.
136             uint L3LinesPerTag();
137             /// L3 cache associativity. L3 cache associativity.
138             uint L3Assoc();
139             /// L3 cache size. Specifies the L3 cache size is within the following range: `(L3Size * 512KB) <= L3 cache size < ((L3Size+1) * 512KB)`.
140             uint L3Size();
141         }
142         else
143         {
144             @trusted @property pure nothrow @nogc:
145 
146             /// EAX
147             mixin(bitfields!(
148                 uint, "L2ITlb4KSize", 11 - 0  + 1,
149                 uint, "L2ITlb4KAssoc", 15 - 12 + 1,
150                 uint, "L2DTlb4KSize", 27 - 16 + 1,
151                 uint, "L2DTlb4KAssoc", 31 - 28 + 1,
152             ));
153 
154             /// EBX
155             mixin(bitfields!(
156                 uint, "L2ITlb2and4MSize", 11 - 0  + 1,
157                 uint, "L2ITlb2and4MAssoc", 15 - 12 + 1,
158                 uint, "L2DTlb2and4MSize", 27 - 16 + 1,
159                 uint, "L2DTlb2and4MAssoc", 31 - 28 + 1,
160             ));
161 
162             /// ECX
163             mixin(bitfields!(
164                 uint, "L2LineSize", 7 - 0 + 1,
165                 uint, "L2LinesPerTag", 11 - 8 + 1,
166                 uint, "L2Assoc", 15 - 12 + 1,
167                 uint, "L2Size", 31 - 16 + 1,
168             ));
169 
170             /// EDX
171             mixin(bitfields!(
172                 uint, "L3LineSize", 7 - 0 + 1,
173                 uint, "L3LinesPerTag", 11 - 8 + 1,
174                 uint, "L3Assoc", 15 - 12 + 1,
175                 uint, "", 17 - 16 + 1,
176                 uint, "L3Size", 31 - 18 + 1,
177             ));
178         }
179     }
180 }
181 
182 /++
183 Long Mode Address Size Identifiers.
184 
185 Extended Feature Extensions ID EBX.
186 
187 Size Identifiers.
188 
189 Specification: AMD
190 +/
191 union LeafExt8Information
192 {
193     /// CPUID payload
194     CpuInfo info;
195 
196     ///
197     struct
198     {
199         import mir.bitmanip: bitfields;
200 
201         version(D_Ddoc)
202         {
203         const @trusted @property pure nothrow @nogc:
204             ///  Maximum physical byte address size in bits
205             uint L2ITlb4KSize();
206             /// Maximum linear byte address size in bits
207             uint PhysAddrSize();
208             /// Maximum guest physical byte address size in bits
209             uint GuestPhysAddrSize();
210             ///  Clear Zero Instruction
211             uint CLZERO();
212             /// Instructions retired count support
213             uint IRPerf();
214             ///
215             uint XSaveErPtr();
216             /// Number of threads in the package - 1
217             uint NC();
218             /// The number of bits in the initial value that indicate thread ID within a package.
219             uint ApicIdCoreIdSize();
220             /// performance time-stamp counter size
221             uint PerfTscSize();
222         }
223         else
224         {
225             @trusted @property pure nothrow @nogc:
226 
227             /// EAX
228             mixin(bitfields!(
229                 uint, "L2ITlb4KSize", 7 - 0  + 1,
230                 uint, "PhysAddrSize", 15 - 8 + 1,
231                 uint, "GuestPhysAddrSize", 23 - 16 + 1,
232                 uint, "", 31 - 24 + 1,
233             ));
234 
235             /// EBX
236             mixin(bitfields!(
237                 bool, "CLZERO", 1,
238                 bool, "IRPerf", 1,
239                 bool, "XSaveErPtr", 1,
240                 uint, "", 31 - 3 + 1,
241             ));
242 
243             /// ECX
244             mixin(bitfields!(
245                 uint, "NC", 7 - 0 + 1,
246                 uint, "", 11 - 8 + 1,
247                 uint, "ApicIdCoreIdSize", 15 - 12 + 1,
248                 uint, "PerfTscSize", 17 - 16 + 1,
249                 uint, "", 31 - 18 + 1,
250             ));
251         }
252     }
253 }
254 
255 /++
256 Extended APIC ID.
257 
258 Core Identifiers.
259 
260 Node Identifiers.
261 
262 Specification: AMD
263 +/
264 union LeafExt1EInformation
265 {
266     /// CPUID payload
267     CpuInfo info;
268 
269     ///
270     struct
271     {
272         import mir.bitmanip: bitfields;
273         // EAX
274         /// Extended APIC ID
275         uint ExtendedApicId;
276         // EBX
277         /// Core ID
278         ubyte CoreId;
279         /// The number of threads per core is ThreadsPerCore+1.
280         ubyte ThreadsPerCore;
281         ushort __reserved__EBX;
282         version(D_Ddoc)
283         {
284         const @trusted @property pure nothrow @nogc:
285             ///  Node per processor.
286             uint NodesPerProcessor();
287             /// Node ID
288             uint NodeId();
289         }
290         else
291         {
292         @trusted @property pure nothrow @nogc:
293 
294             /// ECX
295             mixin(bitfields!(
296                 uint, "", 31 - 11 + 1,
297                 uint, "NodesPerProcessor", 10 - 8 + 1,
298                 uint, "NodeId", 7 - 0 + 1,
299             ));
300         }
301     }
302 }
303 
304 /++
305 Decodes Associativity Fields for L2/L3 Cache or TLB.
306 `T.max` is used to represent full-associative Cache/TLB.
307 +/
308 @safe pure nothrow @nogc
309 T decodeL2or3Assoc(T = uint)(uint assoc)
310 {
311     switch(assoc)
312     {
313         case 0x1: return 1;
314         case 0x2: return 2;
315         case 0x4: return 4;
316         case 0x6: return 8;
317         case 0x8: return 16;
318         case 0xA: return 32;
319         case 0xB: return 48;
320         case 0xC: return 64;
321         case 0xD: return 96;
322         case 0xE: return 128;
323         case 0xF: return T.max;
324         default: return 0;
325     }
326 }