1 /*
2  * Copyright 2008  Veselin Georgiev,
3  * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #ifndef __LIBCPUID_H__
27 #define __LIBCPUID_H__
28 /**
29  * \file     libcpuid.h
30  * \author   Veselin Georgiev
31  * \date     Oct 2008
32  * \version  0.5.1
33  *
34  * Version history:
35  *
36  * * 0.1.0 (2008-10-15): initial adaptation from wxfractgui sources
37  * * 0.1.1 (2009-07-06): Added intel_fn11 fields to cpu_raw_data_t to handle
38  *                       new processor topology enumeration required on Core i7
39  * * 0.1.2 (2009-09-26): Added support for MSR reading through self-extracting
40  *                       kernel driver on Win32.
41  * * 0.1.3 (2010-04-20): Added support for greater more accurate CPU clock
42  *                       measurements with cpu_clock_by_ic()
43  * * 0.2.0 (2011-10-11): Support for AMD Bulldozer CPUs, 128-bit SSE unit size
44  *                       checking. A backwards-incompatible change, since the
45  *                       sizeof cpu_id_t is now different.
46  * * 0.2.1 (2012-05-26): Support for Ivy Bridge, and detecting the presence of
47  *                       the RdRand instruction.
48  * * 0.2.2 (2015-11-04): Support for newer processors up to Haswell and Vishera.
49  *                       Fix clock detection in cpu_clock_by_ic() for Bulldozer.
50  *                       More entries supported in cpu_msrinfo().
51  *                       *BSD and Solaris support (unofficial).
52  * * 0.3.0 (2016-07-09): Support for Skylake; MSR ops in FreeBSD; INFO_VOLTAGE
53  *                       for AMD CPUs. Level 4 cache support for Crystalwell
54  *                       (a backwards-incompatible change since the sizeof
55  *                        cpu_raw_data_t is now different).
56  * * 0.4.0 (2016-09-30): Better detection of AMD clock multiplier with msrinfo.
57  *                       Support for Intel SGX detection
58  *                       (a backwards-incompatible change since the sizeof
59  *                        cpu_raw_data_t and cpu_id_t is now different).
60  * * 0.4.1 (2019-02-05): A lot of DB updates, and better RDMSR
61  * * 0.5.0 (2020-05-23): A lot of DB updates, detection of new CPU features,
62  *                       (a backwards-incompatible change since the sizeof
63  *                        cpu_raw_data_t and cpu_id_t is now different).
64  * * 0.5.1 (2021-03-20): A lot of DB updates
65  */
66 
67 /** @mainpage A simple libcpuid introduction
68  *
69  * LibCPUID provides CPU identification and access to the CPUID and RDTSC
70  * instructions on the x86.
71  * <p>
72  * To execute CPUID, use \ref cpu_exec_cpuid <br>
73  * To execute RDTSC, use \ref cpu_rdtsc <br>
74  * To fetch the CPUID info needed for CPU identification, use
75  *   \ref cpuid_get_raw_data <br>
76  * To make sense of that data (decode, extract features), use \ref cpu_identify <br>
77  * To detect the CPU speed, use either \ref cpu_clock, \ref cpu_clock_by_os,
78  * \ref cpu_tsc_mark + \ref cpu_tsc_unmark + \ref cpu_clock_by_mark,
79  * \ref cpu_clock_measure or \ref cpu_clock_by_ic.
80  * Read carefully for pros/cons of each method. <br>
81  *
82  * To read MSRs, use \ref cpu_msr_driver_open to get a handle, and then
83  * \ref cpu_rdmsr for querying abilities. Some MSR decoding is available on recent
84  * CPUs, and can be queried through \ref cpu_msrinfo; the various types of queries
85  * are described in \ref cpu_msrinfo_request_t.
86  * </p>
87  */
88 
89 /** @defgroup libcpuid LibCPUID
90  * @brief LibCPUID provides CPU identification
91  @{ */
92 
93 /* Include some integer type specifications: */
94 #include "libcpuid_types.h"
95 
96 /* Some limits and other constants */
97 #include "libcpuid_constants.h"
98 
99 #ifdef __cplusplus
100 extern "C" {
101 #endif
102 
103 /**
104  * @brief CPU vendor, as guessed from the Vendor String.
105  */
106 typedef enum {
107 	VENDOR_INTEL = 0,  /*!< Intel CPU */
108 	VENDOR_AMD,        /*!< AMD CPU */
109 	VENDOR_CYRIX,      /*!< Cyrix CPU */
110 	VENDOR_NEXGEN,     /*!< NexGen CPU */
111 	VENDOR_TRANSMETA,  /*!< Transmeta CPU */
112 	VENDOR_UMC,        /*!< x86 CPU by UMC */
113 	VENDOR_CENTAUR,    /*!< x86 CPU by IDT */
114 	VENDOR_RISE,       /*!< x86 CPU by Rise Technology */
115 	VENDOR_SIS,        /*!< x86 CPU by SiS */
116 	VENDOR_NSC,        /*!< x86 CPU by National Semiconductor */
117 	VENDOR_HYGON,	   /*!< Hygon CPU */
118 
119 	NUM_CPU_VENDORS,   /*!< Valid CPU vendor ids: 0..NUM_CPU_VENDORS - 1 */
120 	VENDOR_UNKNOWN = -1,
121 } cpu_vendor_t;
122 #define NUM_CPU_VENDORS NUM_CPU_VENDORS
123 
124 /**
125  * @brief Contains just the raw CPUID data.
126  *
127  * This contains only the most basic CPU data, required to do identification
128  * and feature recognition. Every processor should be identifiable using this
129  * data only.
130  */
131 struct cpu_raw_data_t {
132 	/** contains results of CPUID for eax = 0, 1, ...*/
133 	uint32_t basic_cpuid[MAX_CPUID_LEVEL][NUM_REGS];
134 
135 	/** contains results of CPUID for eax = 0x80000000, 0x80000001, ...*/
136 	uint32_t ext_cpuid[MAX_EXT_CPUID_LEVEL][NUM_REGS];
137 
138 	/** when the CPU is intel and it supports deterministic cache
139 	    information: this contains the results of CPUID for eax = 4
140 	    and ecx = 0, 1, ... */
141 	uint32_t intel_fn4[MAX_INTELFN4_LEVEL][NUM_REGS];
142 
143 	/** when the CPU is intel and it supports leaf 0Bh (Extended Topology
144 	    enumeration leaf), this stores the result of CPUID with
145 	    eax = 11 and ecx = 0, 1, 2... */
146 	uint32_t intel_fn11[MAX_INTELFN11_LEVEL][NUM_REGS];
147 
148 	/** when the CPU is intel and supports leaf 12h (SGX enumeration leaf),
149 	 *  this stores the result of CPUID with eax = 0x12 and
150 	 *  ecx = 0, 1, 2... */
151 	uint32_t intel_fn12h[MAX_INTELFN12H_LEVEL][NUM_REGS];
152 
153 	/** when the CPU is intel and supports leaf 14h (Intel Processor Trace
154 	 *  capabilities leaf).
155 	 *  this stores the result of CPUID with eax = 0x12 and
156 	 *  ecx = 0, 1, 2... */
157 	uint32_t intel_fn14h[MAX_INTELFN14H_LEVEL][NUM_REGS];
158 
159 	/** when the CPU is AMD and supports leaf 8000001Dh
160 	 * (topology information for the DC)
161 	 * this stores the result of CPUID with eax = 8000001Dh and
162 	 *  ecx = 0, 1, 2... */
163 	uint32_t amd_fn8000001dh[MAX_AMDFN8000001DH_LEVEL][NUM_REGS];
164 };
165 
166 /**
167  * @brief This contains information about SGX features of the processor
168  * Example usage:
169  * @code
170  * ...
171  * struct cpu_raw_data_t raw;
172  * struct cpu_id_t id;
173  *
174  * if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0 && id.sgx.present) {
175  *   printf("SGX is present.\n");
176  *   printf("SGX1 instructions: %s.\n", id.sgx.flags[INTEL_SGX1] ? "present" : "absent");
177  *   printf("SGX2 instructions: %s.\n", id.sgx.flags[INTEL_SGX2] ? "present" : "absent");
178  *   printf("Max 32-bit enclave size: 2^%d bytes.\n", id.sgx.max_enclave_32bit);
179  *   printf("Max 64-bit enclave size: 2^%d bytes.\n", id.sgx.max_enclave_64bit);
180  *   for (int i = 0; i < id.sgx.num_epc_sections; i++) {
181  *     struct cpu_epc_t epc = cpuid_get_epc(i, NULL);
182  *     printf("EPC section #%d: address = %x, size = %d bytes.\n", epc.address, epc.size);
183  *   }
184  * } else {
185  *   printf("SGX is not present.\n");
186  * }
187  * @endcode
188  */
189 struct cpu_sgx_t {
190 	/** Whether SGX is present (boolean) */
191 	uint32_t present;
192 
193 	/** Max enclave size in 32-bit mode. This is a power-of-two value:
194 	 *  if it is "31", then the max enclave size is 2^31 bytes (2 GiB).
195 	 */
196 	uint8_t max_enclave_32bit;
197 
198 	/** Max enclave size in 64-bit mode. This is a power-of-two value:
199 	 *  if it is "36", then the max enclave size is 2^36 bytes (64 GiB).
200 	 */
201 	uint8_t max_enclave_64bit;
202 
203 	/**
204 	 * contains SGX feature flags. See the \ref cpu_sgx_feature_t
205 	 * "INTEL_SGX*" macros below.
206 	 */
207 	uint8_t flags[SGX_FLAGS_MAX];
208 
209 	/** number of Enclave Page Cache (EPC) sections. Info for each
210 	 *  section is available through the \ref cpuid_get_epc() function
211 	 */
212 	int num_epc_sections;
213 
214 	/** bit vector of the supported extended  features that can be written
215 	 *  to the MISC region of the SSA (Save State Area)
216 	 */
217 	uint32_t misc_select;
218 
219 	/** a bit vector of the attributes that can be set to SECS.ATTRIBUTES
220 	 *  via ECREATE. Corresponds to bits 0-63 (incl.) of SECS.ATTRIBUTES.
221 	 */
222 	uint64_t secs_attributes;
223 
224 	/** a bit vector of the bits that can be set in the XSAVE feature
225 	 *  request mask; Corresponds to bits 64-127 of SECS.ATTRIBUTES.
226 	 */
227 	uint64_t secs_xfrm;
228 };
229 
230 /**
231  * @brief This contains the recognized CPU features/info
232  */
233 struct cpu_id_t {
234 	/** contains the CPU vendor string, e.g. "GenuineIntel" */
235 	char vendor_str[VENDOR_STR_MAX];
236 
237 	/** contains the brand string, e.g. "Intel(R) Xeon(TM) CPU 2.40GHz" */
238 	char brand_str[BRAND_STR_MAX];
239 
240 	/** contains the recognized CPU vendor */
241 	cpu_vendor_t vendor;
242 
243 	/**
244 	 * contain CPU flags. Used to test for features. See
245 	 * the \ref cpu_feature_t "CPU_FEATURE_*" macros below.
246 	 * @see Features
247 	 */
248 	uint8_t flags[CPU_FLAGS_MAX];
249 
250 	/** CPU family */
251 	int32_t family;
252 
253 	/** CPU model */
254 	int32_t model;
255 
256 	/** CPU stepping */
257 	int32_t stepping;
258 
259 	/** CPU extended family */
260 	int32_t ext_family;
261 
262 	/** CPU extended model */
263 	int32_t ext_model;
264 
265 	/** Number of CPU cores on the current processor */
266 	int32_t num_cores;
267 
268 	/**
269 	 * Number of logical processors on the current processor.
270 	 * Could be more than the number of physical cores,
271 	 * e.g. when the processor has HyperThreading.
272 	 */
273 	int32_t num_logical_cpus;
274 
275 	/**
276 	 * The total number of logical processors.
277 	 * The same value is available through \ref cpuid_get_total_cpus.
278 	 *
279 	 * This is num_logical_cpus * {total physical processors in the system}
280 	 * (but only on a real system, under a VM this number may be lower).
281 	 *
282 	 * If you're writing a multithreaded program and you want to run it on
283 	 * all CPUs, this is the number of threads you need.
284 	 *
285 	 * @note in a VM, this will exactly match the number of CPUs set in
286 	 *       the VM's configuration.
287 	 *
288 	 */
289 	int32_t total_logical_cpus;
290 
291 	/**
292 	 * L1 data cache size in KB. Could be zero, if the CPU lacks cache.
293 	 * If the size cannot be determined, it will be -1.
294 	 */
295 	int32_t l1_data_cache;
296 
297 	/**
298 	 * L1 instruction cache size in KB. Could be zero, if the CPU lacks
299 	 * cache. If the size cannot be determined, it will be -1.
300 	 * @note On some Intel CPUs, whose instruction cache is in fact
301 	 * a trace cache, the size will be expressed in K uOps.
302 	 */
303 	int32_t l1_instruction_cache;
304 
305 	/**
306 	 * L2 cache size in KB. Could be zero, if the CPU lacks L2 cache.
307 	 * If the size of the cache could not be determined, it will be -1
308 	 */
309 	int32_t l2_cache;
310 
311 	/** L3 cache size in KB. Zero on most systems */
312 	int32_t l3_cache;
313 
314 	/** L4 cache size in KB. Zero on most systems */
315 	int32_t l4_cache;
316 
317 	/** Cache associativity for the L1 data cache. -1 if undetermined
318 	 * @deprecated replaced by \ref cpu_id_t::l1_data_assoc
319 	 */
320 	int32_t l1_assoc;
321 
322 	/** Cache associativity for the L1 data cache. -1 if undetermined */
323 	int32_t l1_data_assoc;
324 
325 	/** Cache associativity for the L1 intruction cache. -1 if undetermined */
326 	int32_t l1_instruction_assoc;
327 
328 	/** Cache associativity for the L2 cache. -1 if undetermined */
329 	int32_t l2_assoc;
330 
331 	/** Cache associativity for the L3 cache. -1 if undetermined */
332 	int32_t l3_assoc;
333 
334 	/** Cache associativity for the L4 cache. -1 if undetermined */
335 	int32_t l4_assoc;
336 
337 	/** Cache-line size for L1 data cache. -1 if undetermined
338 	 * @deprecated replaced by \ref cpu_id_t::l1_data_cacheline
339 	 */
340 	int32_t l1_cacheline;
341 
342 	/** Cache-line size for L1 data cache. -1 if undetermined */
343 	int32_t l1_data_cacheline;
344 
345 	/** Cache-line size for L1 intruction cache. -1 if undetermined */
346 	int32_t l1_instruction_cacheline;
347 
348 	/** Cache-line size for L2 cache. -1 if undetermined */
349 	int32_t l2_cacheline;
350 
351 	/** Cache-line size for L3 cache. -1 if undetermined */
352 	int32_t l3_cacheline;
353 
354 	/** Cache-line size for L4 cache. -1 if undetermined */
355 	int32_t l4_cacheline;
356 
357 	/**
358 	 * The brief and human-friendly CPU codename, which was recognized.<br>
359 	 * Examples:
360 	 * @code
361 	 * +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
362 	 * | Vendor | Family | Model | Step. | Cache |       Brand String                    | cpu_id_t.cpu_codename |
363 	 * +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
364 	 * | AMD    |      6 |     8 |     0 |   256 | (not available - will be ignored)     | "K6-2"                |
365 	 * | Intel  |     15 |     2 |     5 |   512 | "Intel(R) Xeon(TM) CPU 2.40GHz"       | "Xeon (Prestonia)"    |
366 	 * | Intel  |      6 |    15 |    11 |  4096 | "Intel(R) Core(TM)2 Duo CPU E6550..." | "Conroe (Core 2 Duo)" |
367 	 * | AMD    |     15 |    35 |     2 |  1024 | "Dual Core AMD Opteron(tm) Proces..." | "Opteron (Dual Core)" |
368 	 * +--------+--------+-------+-------+-------+---------------------------------------+-----------------------+
369 	 * @endcode
370 	 */
371 	char cpu_codename[64];
372 
373 	/** SSE execution unit size (64 or 128; -1 if N/A) */
374 	int32_t sse_size;
375 
376 	/**
377 	 * contain miscellaneous detection information. Used to test about specifics of
378 	 * certain detected features. See \ref cpu_hint_t "CPU_HINT_*" macros below.
379 	 * @see Hints
380 	 */
381 	uint8_t detection_hints[CPU_HINTS_MAX];
382 
383 	/** contains information about SGX features if the processor, if present */
384 	struct cpu_sgx_t sgx;
385 };
386 
387 /**
388  * @brief CPU feature identifiers
389  *
390  * Usage:
391  * @code
392  * ...
393  * struct cpu_raw_data_t raw;
394  * struct cpu_id_t id;
395  * if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0) {
396  *     if (id.flags[CPU_FEATURE_SSE2]) {
397  *         // The CPU has SSE2...
398  *         ...
399  *     } else {
400  *         // no SSE2
401  *     }
402  * } else {
403  *   // processor cannot be determined.
404  * }
405  * @endcode
406  */
407 typedef enum {
408 	CPU_FEATURE_FPU = 0,	/*!< Floating point unit */
409 	CPU_FEATURE_VME,	/*!< Virtual mode extension */
410 	CPU_FEATURE_DE,		/*!< Debugging extension */
411 	CPU_FEATURE_PSE,	/*!< Page size extension */
412 	CPU_FEATURE_TSC,	/*!< Time-stamp counter */
413 	CPU_FEATURE_MSR,	/*!< Model-specific regsisters, RDMSR/WRMSR supported */
414 	CPU_FEATURE_PAE,	/*!< Physical address extension */
415 	CPU_FEATURE_MCE,	/*!< Machine check exception */
416 	CPU_FEATURE_CX8,	/*!< CMPXCHG8B instruction supported */
417 	CPU_FEATURE_APIC,	/*!< APIC support */
418 	CPU_FEATURE_MTRR,	/*!< Memory type range registers */
419 	CPU_FEATURE_SEP,	/*!< SYSENTER / SYSEXIT instructions supported */
420 	CPU_FEATURE_PGE,	/*!< Page global enable */
421 	CPU_FEATURE_MCA,	/*!< Machine check architecture */
422 	CPU_FEATURE_CMOV,	/*!< CMOVxx instructions supported */
423 	CPU_FEATURE_PAT,	/*!< Page attribute table */
424 	CPU_FEATURE_PSE36,	/*!< 36-bit page address extension */
425 	CPU_FEATURE_PN,		/*!< Processor serial # implemented (Intel P3 only) */
426 	CPU_FEATURE_CLFLUSH,	/*!< CLFLUSH instruction supported */
427 	CPU_FEATURE_DTS,	/*!< Debug store supported */
428 	CPU_FEATURE_ACPI,	/*!< ACPI support (power states) */
429 	CPU_FEATURE_MMX,	/*!< MMX instruction set supported */
430 	CPU_FEATURE_FXSR,	/*!< FXSAVE / FXRSTOR supported */
431 	CPU_FEATURE_SSE,	/*!< Streaming-SIMD Extensions (SSE) supported */
432 	CPU_FEATURE_SSE2,	/*!< SSE2 instructions supported */
433 	CPU_FEATURE_SS,		/*!< Self-snoop */
434 	CPU_FEATURE_HT,		/*!< Hyper-threading supported (but might be disabled) */
435 	CPU_FEATURE_TM,		/*!< Thermal monitor */
436 	CPU_FEATURE_IA64,	/*!< IA64 supported (Itanium only) */
437 	CPU_FEATURE_PBE,	/*!< Pending-break enable */
438 	CPU_FEATURE_PNI,	/*!< PNI (SSE3) instructions supported */
439 	CPU_FEATURE_PCLMUL,	/*!< PCLMULQDQ instruction supported */
440 	CPU_FEATURE_DTS64,	/*!< 64-bit Debug store supported */
441 	CPU_FEATURE_MONITOR,	/*!< MONITOR / MWAIT supported */
442 	CPU_FEATURE_DS_CPL,	/*!< CPL Qualified Debug Store */
443 	CPU_FEATURE_VMX,	/*!< Virtualization technology supported */
444 	CPU_FEATURE_SMX,	/*!< Safer mode exceptions */
445 	CPU_FEATURE_EST,	/*!< Enhanced SpeedStep */
446 	CPU_FEATURE_TM2,	/*!< Thermal monitor 2 */
447 	CPU_FEATURE_SSSE3,	/*!< SSSE3 instructionss supported (this is different from SSE3!) */
448 	CPU_FEATURE_CID,	/*!< Context ID supported */
449 	CPU_FEATURE_CX16,	/*!< CMPXCHG16B instruction supported */
450 	CPU_FEATURE_XTPR,	/*!< Send Task Priority Messages disable */
451 	CPU_FEATURE_PDCM,	/*!< Performance capabilities MSR supported */
452 	CPU_FEATURE_DCA,	/*!< Direct cache access supported */
453 	CPU_FEATURE_SSE4_1,	/*!< SSE 4.1 instructions supported */
454 	CPU_FEATURE_SSE4_2,	/*!< SSE 4.2 instructions supported */
455 	CPU_FEATURE_SYSCALL,	/*!< SYSCALL / SYSRET instructions supported */
456 	CPU_FEATURE_XD,		/*!< Execute disable bit supported */
457 	CPU_FEATURE_MOVBE,	/*!< MOVBE instruction supported */
458 	CPU_FEATURE_POPCNT,	/*!< POPCNT instruction supported */
459 	CPU_FEATURE_AES,	/*!< AES* instructions supported */
460 	CPU_FEATURE_XSAVE,	/*!< XSAVE/XRSTOR/etc instructions supported */
461 	CPU_FEATURE_OSXSAVE,	/*!< non-privileged copy of OSXSAVE supported */
462 	CPU_FEATURE_AVX,	/*!< Advanced vector extensions supported */
463 	CPU_FEATURE_MMXEXT,	/*!< AMD MMX-extended instructions supported */
464 	CPU_FEATURE_3DNOW,	/*!< AMD 3DNow! instructions supported */
465 	CPU_FEATURE_3DNOWEXT,	/*!< AMD 3DNow! extended instructions supported */
466 	CPU_FEATURE_NX,		/*!< No-execute bit supported */
467 	CPU_FEATURE_FXSR_OPT,	/*!< FFXSR: FXSAVE and FXRSTOR optimizations */
468 	CPU_FEATURE_RDTSCP,	/*!< RDTSCP instruction supported (AMD-only) */
469 	CPU_FEATURE_LM,		/*!< Long mode (x86_64/EM64T) supported */
470 	CPU_FEATURE_LAHF_LM,	/*!< LAHF/SAHF supported in 64-bit mode */
471 	CPU_FEATURE_CMP_LEGACY,	/*!< core multi-processing legacy mode */
472 	CPU_FEATURE_SVM,	/*!< AMD Secure virtual machine */
473 	CPU_FEATURE_ABM,	/*!< LZCNT instruction support */
474 	CPU_FEATURE_MISALIGNSSE,/*!< Misaligned SSE supported */
475 	CPU_FEATURE_SSE4A,	/*!< SSE 4a from AMD */
476 	CPU_FEATURE_3DNOWPREFETCH,	/*!< PREFETCH/PREFETCHW support */
477 	CPU_FEATURE_OSVW,	/*!< OS Visible Workaround (AMD) */
478 	CPU_FEATURE_IBS,	/*!< Instruction-based sampling */
479 	CPU_FEATURE_SSE5,	/*!< SSE 5 instructions supported (deprecated, will never be 1) */
480 	CPU_FEATURE_SKINIT,	/*!< SKINIT / STGI supported */
481 	CPU_FEATURE_WDT,	/*!< Watchdog timer support */
482 	CPU_FEATURE_TS,		/*!< Temperature sensor */
483 	CPU_FEATURE_FID,	/*!< Frequency ID control */
484 	CPU_FEATURE_VID,	/*!< Voltage ID control */
485 	CPU_FEATURE_TTP,	/*!< THERMTRIP */
486 	CPU_FEATURE_TM_AMD,	/*!< AMD-specified hardware thermal control */
487 	CPU_FEATURE_STC,	/*!< Software thermal control */
488 	CPU_FEATURE_100MHZSTEPS,/*!< 100 MHz multiplier control */
489 	CPU_FEATURE_HWPSTATE,	/*!< Hardware P-state control */
490 	CPU_FEATURE_CONSTANT_TSC,	/*!< TSC ticks at constant rate */
491 	CPU_FEATURE_XOP,	/*!< The XOP instruction set (same as the old CPU_FEATURE_SSE5) */
492 	CPU_FEATURE_FMA3,	/*!< The FMA3 instruction set */
493 	CPU_FEATURE_FMA4,	/*!< The FMA4 instruction set */
494 	CPU_FEATURE_TBM,	/*!< Trailing bit manipulation instruction support */
495 	CPU_FEATURE_F16C,	/*!< 16-bit FP convert instruction support */
496 	CPU_FEATURE_RDRAND,     /*!< RdRand instruction */
497 	CPU_FEATURE_X2APIC,     /*!< x2APIC, APIC_BASE.EXTD, MSRs 0000_0800h...0000_0BFFh 64-bit ICR (+030h but not +031h), no DFR (+00Eh), SELF_IPI (+040h) also see standard level 0000_000Bh */
498 	CPU_FEATURE_CPB,	/*!< Core performance boost */
499 	CPU_FEATURE_APERFMPERF,	/*!< MPERF/APERF MSRs support */
500 	CPU_FEATURE_PFI,	/*!< Processor Feedback Interface support */
501 	CPU_FEATURE_PA,		/*!< Processor accumulator */
502 	CPU_FEATURE_AVX2,	/*!< AVX2 instructions */
503 	CPU_FEATURE_BMI1,	/*!< BMI1 instructions */
504 	CPU_FEATURE_BMI2,	/*!< BMI2 instructions */
505 	CPU_FEATURE_HLE,	/*!< Hardware Lock Elision prefixes */
506 	CPU_FEATURE_RTM,	/*!< Restricted Transactional Memory instructions */
507 	CPU_FEATURE_AVX512F,	/*!< AVX-512 Foundation */
508 	CPU_FEATURE_AVX512DQ,	/*!< AVX-512 Double/Quad granular insns */
509 	CPU_FEATURE_AVX512PF,	/*!< AVX-512 Prefetch */
510 	CPU_FEATURE_AVX512ER,	/*!< AVX-512 Exponential/Reciprocal */
511 	CPU_FEATURE_AVX512CD,	/*!< AVX-512 Conflict detection */
512 	CPU_FEATURE_SHA_NI,	/*!< SHA-1/SHA-256 instructions */
513 	CPU_FEATURE_AVX512BW,	/*!< AVX-512 Byte/Word granular insns */
514 	CPU_FEATURE_AVX512VL,	/*!< AVX-512 128/256 vector length extensions */
515 	CPU_FEATURE_SGX,	/*!< SGX extensions. Non-autoritative, check cpu_id_t::sgx::present to verify presence */
516 	CPU_FEATURE_RDSEED,	/*!< RDSEED instruction */
517 	CPU_FEATURE_ADX,	/*!< ADX extensions (arbitrary precision) */
518 	CPU_FEATURE_AVX512VNNI, /*!< AVX-512 Vector Neural Network Instructions */
519 	CPU_FEATURE_AVX512VBMI, /*!< AVX-512 Vector Bit ManipulationInstructions (version 1) */
520 	CPU_FEATURE_AVX512VBMI2, /*!< AVX-512 Vector Bit ManipulationInstructions (version 2) */
521 	/* termination: */
522 	NUM_CPU_FEATURES,
523 } cpu_feature_t;
524 
525 /**
526  * @brief CPU detection hints identifiers
527  *
528  * Usage: similar to the flags usage
529  */
530 typedef enum {
531 	CPU_HINT_SSE_SIZE_AUTH = 0,	/*!< SSE unit size is authoritative (not only a Family/Model guesswork, but based on an actual CPUID bit) */
532 	/* termination */
533 	NUM_CPU_HINTS,
534 } cpu_hint_t;
535 
536 /**
537  * @brief SGX features flags
538  * \see cpu_sgx_t
539  *
540  * Usage:
541  * @code
542  * ...
543  * struct cpu_raw_data_t raw;
544  * struct cpu_id_t id;
545  * if (cpuid_get_raw_data(&raw) == 0 && cpu_identify(&raw, &id) == 0 && id.sgx.present) {
546  *     if (id.sgx.flags[INTEL_SGX1])
547  *         // The CPU has SGX1 instructions support...
548  *         ...
549  *     } else {
550  *         // no SGX
551  *     }
552  * } else {
553  *   // processor cannot be determined.
554  * }
555  * @endcode
556  */
557 
558 typedef enum {
559 	INTEL_SGX1,		/*!< SGX1 instructions support */
560 	INTEL_SGX2,		/*!< SGX2 instructions support */
561 
562 	/* termination: */
563 	NUM_SGX_FEATURES,
564 } cpu_sgx_feature_t;
565 
566 /**
567  * @brief Describes common library error codes
568  */
569 typedef enum {
570 	ERR_OK       =  0,	/*!< No error */
571 	ERR_NO_CPUID = -1,	/*!< CPUID instruction is not supported */
572 	ERR_NO_RDTSC = -2,	/*!< RDTSC instruction is not supported */
573 	ERR_NO_MEM   = -3,	/*!< Memory allocation failed */
574 	ERR_OPEN     = -4,	/*!< File open operation failed */
575 	ERR_BADFMT   = -5,	/*!< Bad file format */
576 	ERR_NOT_IMP  = -6,	/*!< Not implemented */
577 	ERR_CPU_UNKN = -7,	/*!< Unsupported processor */
578 	ERR_NO_RDMSR = -8,	/*!< RDMSR instruction is not supported */
579 	ERR_NO_DRIVER= -9,	/*!< RDMSR driver error (generic) */
580 	ERR_NO_PERMS = -10,	/*!< No permissions to install RDMSR driver */
581 	ERR_EXTRACT  = -11,	/*!< Cannot extract RDMSR driver (read only media?) */
582 	ERR_HANDLE   = -12,	/*!< Bad handle */
583 	ERR_INVMSR   = -13,	/*!< Invalid MSR */
584 	ERR_INVCNB   = -14,	/*!< Invalid core number */
585 	ERR_HANDLE_R = -15,	/*!< Error on handle read */
586 	ERR_INVRANGE = -16,	/*!< Invalid given range */
587 } cpu_error_t;
588 
589 /**
590  * @brief Internal structure, used in cpu_tsc_mark, cpu_tsc_unmark and
591  *        cpu_clock_by_mark
592  */
593 struct cpu_mark_t {
594 	uint64_t tsc;		/*!< Time-stamp from RDTSC */
595 	uint64_t sys_clock;	/*!< In microsecond resolution */
596 };
597 
598 /**
599  * @brief Returns the total number of logical CPU threads (even if CPUID is not present).
600  *
601  * Under VM, this number (and total_logical_cpus, since they are fetched with the same code)
602  * may be nonsensical, i.e. might not equal NumPhysicalCPUs*NumCoresPerCPU*HyperThreading.
603  * This is because no matter how many logical threads the host machine has, you may limit them
604  * in the VM to any number you like. **This** is the number returned by cpuid_get_total_cpus().
605  *
606  * @returns Number of logical CPU threads available. Equals the \ref cpu_id_t::total_logical_cpus.
607  */
608 int cpuid_get_total_cpus(void);
609 
610 /**
611  * @brief Checks if the CPUID instruction is supported
612  * @retval 1 if CPUID is present
613  * @retval 0 the CPU doesn't have CPUID.
614  */
615 int cpuid_present(void);
616 
617 /**
618  * @brief Executes the CPUID instruction
619  * @param eax - the value of the EAX register when executing CPUID
620  * @param regs - the results will be stored here. regs[0] = EAX, regs[1] = EBX, ...
621  * @note CPUID will be executed with EAX set to the given value and EBX, ECX,
622  *       EDX set to zero.
623  */
624 void cpu_exec_cpuid(uint32_t eax, uint32_t* regs);
625 
626 /**
627  * @brief Executes the CPUID instruction with the given input registers
628  * @note This is just a bit more generic version of cpu_exec_cpuid - it allows
629  *       you to control all the registers.
630  * @param regs - Input/output. Prior to executing CPUID, EAX, EBX, ECX and
631  *               EDX will be set to regs[0], regs[1], regs[2] and regs[3].
632  *               After CPUID, this array will contain the results.
633  */
634 void cpu_exec_cpuid_ext(uint32_t* regs);
635 
636 /**
637  * @brief Obtains the raw CPUID data from the current CPU
638  * @param data - a pointer to cpu_raw_data_t structure
639  * @returns zero if successful, and some negative number on error.
640  *          The error message can be obtained by calling \ref cpuid_error.
641  *          @see cpu_error_t
642  */
643 int cpuid_get_raw_data(struct cpu_raw_data_t* data);
644 
645 /**
646  * @brief Writes the raw CPUID data to a text file
647  * @param data - a pointer to cpu_raw_data_t structure
648  * @param filename - the path of the file, where the serialized data should be
649  *                   written. If empty, stdout will be used.
650  * @note This is intended primarily for debugging. On some processor, which is
651  *       not currently supported or not completely recognized by cpu_identify,
652  *       one can still successfully get the raw data and write it to a file.
653  *       libcpuid developers can later import this file and debug the detection
654  *       code as if running on the actual hardware.
655  *       The file is simple text format of "something=value" pairs. Version info
656  *       is also written, but the format is not intended to be neither backward-
657  *       nor forward compatible.
658  * @returns zero if successful, and some negative number on error.
659  *          The error message can be obtained by calling \ref cpuid_error.
660  *          @see cpu_error_t
661  */
662 int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
663 
664 /**
665  * @brief Reads raw CPUID data from file
666  * @param data - a pointer to cpu_raw_data_t structure. The deserialized data will
667  *               be written here.
668  * @param filename - the path of the file, containing the serialized raw data.
669  *                   If empty, stdin will be used.
670  * @note This function may fail, if the file is created by different version of
671  *       the library. Also, see the notes on cpuid_serialize_raw_data.
672  * @returns zero if successful, and some negative number on error.
673  *          The error message can be obtained by calling \ref cpuid_error.
674  *          @see cpu_error_t
675 */
676 int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
677 
678 /**
679  * @brief Identifies the CPU
680  * @param raw - Input - a pointer to the raw CPUID data, which is obtained
681  *              either by cpuid_get_raw_data or cpuid_deserialize_raw_data.
682  *              Can also be NULL, in which case the functions calls
683  *              cpuid_get_raw_data itself.
684  * @param data - Output - the decoded CPU features/info is written here.
685  * @note The function will not fail, even if some of the information
686  *       cannot be obtained. Even when the CPU is new and thus unknown to
687  *       libcpuid, some generic info, such as "AMD K9 family CPU" will be
688  *       written to data.cpu_codename, and most other things, such as the
689  *       CPU flags, cache sizes, etc. should be detected correctly anyway.
690  *       However, the function CAN fail, if the CPU is completely alien to
691  *       libcpuid.
692  * @note While cpu_identify() and cpuid_get_raw_data() are fast for most
693  *       purposes, running them several thousand times per second can hamper
694  *       performance significantly. Specifically, avoid writing "cpu feature
695  *       checker" wrapping function, which calls cpu_identify and returns the
696  *       value of some flag, if that function is going to be called frequently.
697  * @returns zero if successful, and some negative number on error.
698  *          The error message can be obtained by calling \ref cpuid_error.
699  *          @see cpu_error_t
700  */
701 int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
702 
703 /**
704  * @brief Returns the short textual representation of a CPU flag
705  * @param feature - the feature, whose textual representation is wanted.
706  * @returns a constant string like "fpu", "tsc", "sse2", etc.
707  * @note the names of the returned flags are compatible with those from
708  *       /proc/cpuinfo in Linux, with the exception of `tm_amd'
709  */
710 const char* cpu_feature_str(cpu_feature_t feature);
711 
712 /**
713  * @brief Returns textual description of the last error
714  *
715  * libcpuid stores an `errno'-style error status, whose description
716  * can be obtained with this function.
717  * @note This function is not thread-safe
718  * @see cpu_error_t
719  */
720 const char* cpuid_error(void);
721 
722 /**
723  * @brief Executes RDTSC
724  *
725  * The RDTSC (ReaD Time Stamp Counter) instruction gives access to an
726  * internal 64-bit counter, which usually increments at each clock cycle.
727  * This can be used for various timing routines, and as a very precise
728  * clock source. It is set to zero on system startup. Beware that may not
729  * increment at the same frequency as the CPU. Consecutive calls of RDTSC
730  * are, however, guaranteed to return monotonically-increasing values.
731  *
732  * @param result - a pointer to a 64-bit unsigned integer, where the TSC value
733  *                 will be stored
734  *
735  * @note  If 100% compatibility is a concern, you must first check if the
736  * RDTSC instruction is present (if it is not, your program will crash
737  * with "invalid opcode" exception). Only some very old processors (i486,
738  * early AMD K5 and some Cyrix CPUs) lack that instruction - they should
739  * have become exceedingly rare these days. To verify RDTSC presence,
740  * run cpu_identify() and check flags[CPU_FEATURE_TSC].
741  *
742  * @note The monotonically increasing nature of the TSC may be violated
743  * on SMP systems, if their TSC clocks run at different rate. If the OS
744  * doesn't account for that, the TSC drift may become arbitrary large.
745  */
746 void cpu_rdtsc(uint64_t* result);
747 
748 /**
749  * @brief Store TSC and timing info
750  *
751  * This function stores the current TSC value and current
752  * time info from a precise OS-specific clock source in the cpu_mark_t
753  * structure. The sys_clock field contains time with microsecond resolution.
754  * The values can later be used to measure time intervals, number of clocks,
755  * FPU frequency, etc.
756  * @see cpu_rdtsc
757  *
758  * @param mark [out] - a pointer to a cpu_mark_t structure
759  */
760 void cpu_tsc_mark(struct cpu_mark_t* mark);
761 
762 /**
763  * @brief Calculate TSC and timing difference
764  *
765  * @param mark - input/output: a pointer to a cpu_mark_t structure, which has
766  *               already been initialized by cpu_tsc_mark. The difference in
767  *               TSC and time will be written here.
768  *
769  * This function calculates the TSC and time difference, by obtaining the
770  * current TSC and timing values and subtracting the contents of the `mark'
771  * structure from them. Results are written in the same structure.
772  *
773  * Example:
774  * @code
775  * ...
776  * struct cpu_mark_t mark;
777  * cpu_tsc_mark(&mark);
778  * foo();
779  * cpu_tsc_unmark(&mark);
780  * printf("Foo finished. Executed in %llu cycles and %llu usecs\n",
781  *        mark.tsc, mark.sys_clock);
782  * ...
783  * @endcode
784  */
785 void cpu_tsc_unmark(struct cpu_mark_t* mark);
786 
787 /**
788  * @brief Calculates the CPU clock
789  *
790  * @param mark - pointer to a cpu_mark_t structure, which has been initialized
791  *   with cpu_tsc_mark and later `stopped' with cpu_tsc_unmark.
792  *
793  * @note For reliable results, the marked time interval should be at least about
794  * 10 ms.
795  *
796  * @returns the CPU clock frequency, in MHz. Due to measurement error, it will
797  * differ from the true value in a few least-significant bits. Accuracy depends
798  * on the timing interval - the more, the better. If the timing interval is
799  * insufficient, the result is -1. Also, see the comment on cpu_clock_measure
800  * for additional issues and pitfalls in using RDTSC for CPU frequency
801  * measurements.
802  */
803 int cpu_clock_by_mark(struct cpu_mark_t* mark);
804 
805 /**
806  * @brief Returns the CPU clock, as reported by the OS
807  *
808  * This function uses OS-specific functions to obtain the CPU clock. It may
809  * differ from the true clock for several reasons:<br><br>
810  *
811  * i) The CPU might be in some power saving state, while the OS reports its
812  *    full-power frequency, or vice-versa.<br>
813  * ii) In some cases you can raise or lower the CPU frequency with overclocking
814  *     utilities and the OS will not notice.
815  *
816  * @returns the CPU clock frequency in MHz. If the OS is not (yet) supported
817  * or lacks the necessary reporting machinery, the return value is -1
818  */
819 int cpu_clock_by_os(void);
820 
821 /**
822  * @brief Measure the CPU clock frequency
823  *
824  * @param millis - How much time to waste in the busy-wait cycle. In millisecs.
825  *                 Useful values 10 - 1000
826  * @param quad_check - Do a more thorough measurement if nonzero
827  *                     (see the explanation).
828  *
829  * The function performs a busy-wait cycle for the given time and calculates
830  * the CPU frequency by the difference of the TSC values. The accuracy of the
831  * calculation depends on the length of the busy-wait cycle: more is better,
832  * but 100ms should be enough for most purposes.
833  *
834  * While this will calculate the CPU frequency correctly in most cases, there are
835  * several reasons why it might be incorrect:<br>
836  *
837  * i) RDTSC doesn't guarantee it will run at the same clock as the CPU.
838  *    Apparently there aren't CPUs at the moment, but still, there's no
839  *    guarantee.<br>
840  * ii) The CPU might be in a low-frequency power saving mode, and the CPU
841  *     might be switched to higher frequency at any time. If this happens
842  *     during the measurement, the result can be anywhere between the
843  *     low and high frequencies. Also, if you're interested in the
844  *     high frequency value only, this function might return the low one
845  *     instead.<br>
846  * iii) On SMP systems exhibiting TSC drift (see \ref cpu_rdtsc)
847  *
848  * the quad_check option will run four consecutive measurements and
849  * then return the average of the two most-consistent results. The total
850  * runtime of the function will still be `millis' - consider using
851  * a bit more time for the timing interval.
852  *
853  * Finally, for benchmarking / CPU intensive applications, the best strategy is
854  * to use the cpu_tsc_mark() / cpu_tsc_unmark() / cpu_clock_by_mark() method.
855  * Begin by mark()-ing about one second after application startup (allowing the
856  * power-saving manager to kick in and rise the frequency during that time),
857  * then unmark() just before application finishing. The result will most
858  * acurately represent at what frequency your app was running.
859  *
860  * @returns the CPU clock frequency in MHz (within some measurement error
861  * margin). If RDTSC is not supported, the result is -1.
862  */
863 int cpu_clock_measure(int millis, int quad_check);
864 
865 /**
866  * @brief Measure the CPU clock frequency using instruction-counting
867  *
868  * @param millis - how much time to allocate for each run, in milliseconds
869  * @param runs - how many runs to perform
870  *
871  * The function performs a busy-wait cycle using a known number of "heavy" (SSE)
872  * instructions. These instructions run at (more or less guaranteed) 1 IPC rate,
873  * so by running a busy loop for a fixed amount of time, and measuring the
874  * amount of instructions done, the CPU clock is accurately measured.
875  *
876  * Of course, this function is still affected by the power-saving schemes, so
877  * the warnings as of cpu_clock_measure() still apply. However, this function is
878  * immune to problems with detection, related to the Intel Nehalem's "Turbo"
879  * mode, where the internal clock is raised, but the RDTSC rate is unaffected.
880  *
881  * The function will run for about (millis * runs) milliseconds.
882  * You can make only a single busy-wait run (runs == 1); however, this can
883  * be affected by task scheduling (which will break the counting), so allowing
884  * more than one run is recommended. As run length is not imperative for
885  * accurate readings (e.g., 50ms is sufficient), you can afford a lot of short
886  * runs, e.g. 10 runs of 50ms or 20 runs of 25ms.
887  *
888  * Recommended values - millis = 50, runs = 4. For more robustness,
889  * increase the number of runs.
890  *
891  * NOTE: on Bulldozer and later CPUs, the busy-wait cycle runs at 1.4 IPC, thus
892  * the results are skewed. This is corrected internally by dividing the resulting
893  * value by 1.4.
894  * However, this only occurs if the thread is executed on a single CMT
895  * module - if there are other threads competing for resources, the results are
896  * unpredictable. Make sure you run cpu_clock_by_ic() on a CPU that is free from
897  * competing threads, or if there are such threads, they shouldn't exceed the
898  * number of modules. On a Bulldozer X8, that means 4 threads.
899  *
900  * @returns the CPU clock frequency in MHz (within some measurement error
901  * margin). If SSE is not supported, the result is -1. If the input parameters
902  * are incorrect, or some other internal fault is detected, the result is -2.
903  */
904 int cpu_clock_by_ic(int millis, int runs);
905 
906 /**
907  * @brief Get the CPU clock frequency (all-in-one method)
908  *
909  * This is an all-in-one method for getting the CPU clock frequency.
910  * It tries to use the OS for that. If the OS doesn't have this info, it
911  * uses cpu_clock_measure with 200ms time interval and quadruple checking.
912  *
913  * @returns the CPU clock frequency in MHz. If every possible method fails,
914  * the result is -1.
915  */
916 int cpu_clock(void);
917 
918 
919 /**
920  * @brief The return value of cpuid_get_epc().
921  * @details
922  * Describes an EPC (Enclave Page Cache) layout (physical address and size).
923  * A CPU may have one or more EPC areas, and information about each is
924  * fetched via \ref cpuid_get_epc.
925  */
926 struct cpu_epc_t {
927 	uint64_t start_addr;
928 	uint64_t length;
929 };
930 
931 /**
932  * @brief Fetches information about an EPC (Enclave Page Cache) area.
933  * @param index - zero-based index, valid range [0..cpu_id_t.egx.num_epc_sections)
934  * @param raw   - a pointer to fetched raw CPUID data. Needed only for testing,
935  *                you can safely pass NULL here (if you pass a real structure,
936  *                it will be used for fetching the leaf 12h data if index < 2;
937  *                otherwise the real CPUID instruction will be used).
938  * @returns the requested data. If the CPU doesn't support SGX, or if
939  *          index >= cpu_id_t.egx.num_epc_sections, both fields of the returned
940  *          structure will be zeros.
941  */
942 struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
943 
944 /**
945  * @brief Returns the libcpuid version
946  *
947  * @returns the string representation of the libcpuid version, like "0.1.1"
948  */
949 const char* cpuid_lib_version(void);
950 
951 typedef void (*libcpuid_warn_fn_t) (const char *msg);
952 /**
953  * @brief Sets the warning print function
954  *
955  * In some cases, the internal libcpuid machinery would like to emit useful
956  * debug warnings. By default, these warnings are written to stderr. However,
957  * you can set a custom function that will receive those warnings.
958  *
959  * @param warn_fun - the warning function you want to set. If NULL, warnings
960  *                   are disabled. The function takes const char* argument.
961  *
962  * @returns the current warning function. You can use the return value to
963  * keep the previous warning function and restore it at your discretion.
964  */
965 libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t warn_fun);
966 
967 /**
968  * @brief Sets the verbosiness level
969  *
970  * When the verbosiness level is above zero, some functions might print
971  * diagnostic information about what are they doing. The higher the level is,
972  * the more detail is printed. Level zero is guaranteed to omit all such
973  * output. The output is written using the same machinery as the warnings,
974  * @see cpuid_set_warn_function()
975  *
976  * @param level the desired verbosiness level. Useful values 0..2 inclusive
977  */
978 void cpuid_set_verbosiness_level(int level);
979 
980 
981 /**
982  * @brief Obtains the CPU vendor from CPUID from the current CPU
983  * @note The result is cached.
984  * @returns VENDOR_UNKNOWN if failed, otherwise the CPU vendor type.
985  *          @see cpu_vendor_t
986  */
987 cpu_vendor_t cpuid_get_vendor(void);
988 
989 /**
990  * @brief a structure that holds a list of processor names
991  */
992 struct cpu_list_t {
993 	/** Number of entries in the list */
994 	int num_entries;
995 	/** Pointers to names. There will be num_entries of them */
996 	char **names;
997 };
998 
999 /**
1000  * @brief Gets a list of all known CPU names from a specific vendor.
1001  *
1002  * This function compiles a list of all known CPU (code)names
1003  * (i.e. the possible values of cpu_id_t::cpu_codename) for the given vendor.
1004  *
1005  * There are about 100 entries for Intel and AMD, and a few for the other
1006  * vendors. The list is written out in approximate chronological introduction
1007  * order of the parts.
1008  *
1009  * @param vendor the vendor to be queried
1010  * @param list [out] the resulting list will be written here.
1011  * NOTE: As the memory is dynamically allocated, be sure to call
1012  *       cpuid_free_cpu_list() after you're done with the data
1013  * @see cpu_list_t
1014  */
1015 void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list);
1016 
1017 /**
1018  * @brief Frees a CPU list
1019  *
1020  * This function deletes all the memory associated with a CPU list, as obtained
1021  * by cpuid_get_cpu_list()
1022  *
1023  * @param list - the list to be free()'d.
1024  */
1025 void cpuid_free_cpu_list(struct cpu_list_t* list);
1026 
1027 struct msr_driver_t;
1028 /**
1029  * @brief Starts/opens a driver, needed to read MSRs (Model Specific Registers)
1030  *
1031  * On systems that support it, this function will create a temporary
1032  * system driver, that has privileges to execute the RDMSR instruction.
1033  * After the driver is created, you can read MSRs by calling \ref cpu_rdmsr
1034  *
1035  * @returns a handle to the driver on success, and NULL on error.
1036  *          The error message can be obtained by calling \ref cpuid_error.
1037  *          @see cpu_error_t
1038  */
1039 struct msr_driver_t* cpu_msr_driver_open(void);
1040 
1041 /**
1042  * @brief Similar to \ref cpu_msr_driver_open, but accept one parameter
1043  *
1044  * This function works on certain operating systems (GNU/Linux, FreeBSD)
1045  *
1046  * @param core_num specify the core number for MSR.
1047  *          The first core number is 0.
1048  *          The last core number is \ref cpuid_get_total_cpus - 1.
1049  *
1050  * @returns a handle to the driver on success, and NULL on error.
1051  *          The error message can be obtained by calling \ref cpuid_error.
1052  *          @see cpu_error_t
1053  */
1054 struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num);
1055 
1056 /**
1057  * @brief Reads a Model-Specific Register (MSR)
1058  *
1059  * If the CPU has MSRs (as indicated by the CPU_FEATURE_MSR flag), you can
1060  * read a MSR with the given index by calling this function.
1061  *
1062  * There are several prerequisites you must do before reading MSRs:
1063  * 1) You must ensure the CPU has RDMSR. Check the CPU_FEATURE_MSR flag
1064  *    in cpu_id_t::flags
1065  * 2) You must ensure that the CPU implements the specific MSR you intend to
1066  *    read.
1067  * 3) You must open a MSR-reader driver. RDMSR is a privileged instruction and
1068  *    needs ring-0 access in order to work. This temporary driver is created
1069  *    by calling \ref cpu_msr_driver_open
1070  *
1071  * @param handle - a handle to the MSR reader driver, as created by
1072  *                 cpu_msr_driver_open
1073  * @param msr_index - the numeric ID of the MSR you want to read
1074  * @param result - a pointer to a 64-bit integer, where the MSR value is stored
1075  *
1076  * @returns zero if successful, and some negative number on error.
1077  *          The error message can be obtained by calling \ref cpuid_error.
1078  *          @see cpu_error_t
1079  */
1080 int cpu_rdmsr(struct msr_driver_t* handle, uint32_t msr_index, uint64_t* result);
1081 
1082 
1083 typedef enum {
1084 	INFO_MPERF,                /*!< Maximum performance frequency clock. This
1085                                     is a counter, which increments as a
1086                                     proportion of the actual processor speed. */
1087 	INFO_APERF,                /*!< Actual performance frequency clock. This
1088                                     accumulates the core clock counts when the
1089                                     core is active. */
1090 	INFO_MIN_MULTIPLIER,       /*!< Minimum CPU:FSB ratio for this CPU,
1091                                     multiplied by 100. */
1092 	INFO_CUR_MULTIPLIER,       /*!< Current CPU:FSB ratio, multiplied by 100.
1093                                     e.g., a CPU:FSB value of 18.5 reads as
1094                                     "1850". */
1095 	INFO_MAX_MULTIPLIER,       /*!< Maximum CPU:FSB ratio for this CPU,
1096                                     multiplied by 100. */
1097 	INFO_TEMPERATURE,          /*!< The current core temperature in Celsius. */
1098 	INFO_THROTTLING,           /*!< 1 if the current logical processor is
1099                                     throttling. 0 if it is running normally. */
1100 	INFO_VOLTAGE,              /*!< The current core voltage in Volt,
1101 	                            multiplied by 100. */
1102 	INFO_BCLK,                 /*!< See \ref INFO_BUS_CLOCK. */
1103 	INFO_BUS_CLOCK,            /*!< The main bus clock in MHz,
1104 	                            e.g., FSB/QPI/DMI/HT base clock,
1105 	                            multiplied by 100. */
1106 } cpu_msrinfo_request_t;
1107 
1108 /**
1109  * @brief Similar to \ref cpu_rdmsr, but extract a range of bits
1110  *
1111  * @param handle - a handle to the MSR reader driver, as created by
1112  *                 cpu_msr_driver_open
1113  * @param msr_index - the numeric ID of the MSR you want to read
1114  * @param highbit - the high bit in range, must be inferior to 64
1115  * @param lowbit - the low bit in range, must be equal or superior to 0
1116  * @param result - a pointer to a 64-bit integer, where the MSR value is stored
1117  *
1118  * @returns zero if successful, and some negative number on error.
1119  *          The error message can be obtained by calling \ref cpuid_error.
1120  *          @see cpu_error_t
1121  */
1122 int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
1123                     uint8_t lowbit, uint64_t* result);
1124 
1125 /**
1126  * @brief Reads extended CPU information from Model-Specific Registers.
1127  * @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open
1128  * @param which - which info field should be returned. A list of
1129  *                available information entities is listed in the
1130  *                cpu_msrinfo_request_t enum.
1131  * @retval - if the requested information is available for the current
1132  *           processor model, the respective value is returned.
1133  *           if no information is available, or the CPU doesn't support
1134  *           the query, the special value CPU_INVALID_VALUE is returned
1135  * @note This function is not MT-safe. If you intend to call it from multiple
1136  *       threads, guard it through a mutex or a similar primitive.
1137  */
1138 int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which);
1139 #define CPU_INVALID_VALUE 0x3fffffff
1140 
1141 /**
1142  * @brief Writes the raw MSR data to a text file
1143  * @param handle -  a handle to the MSR reader driver, as created by cpu_msr_driver_open
1144  * @param filename - the path of the file, where the serialized data should be
1145  *                   written. If empty, stdout will be used.
1146  * @note This is intended primarily for debugging. On some processor, which is
1147  *       not currently supported or not completely recognized by cpu_identify,
1148  *       one can still successfully get the raw data and write it to a file.
1149  *       libcpuid developers can later import this file and debug the detection
1150  *       code as if running on the actual hardware.
1151  *       The file is simple text format of "something=value" pairs. Version info
1152  *       is also written, but the format is not intended to be neither backward-
1153  *       nor forward compatible.
1154  * @returns zero if successful, and some negative number on error.
1155  *          The error message can be obtained by calling \ref cpuid_error.
1156  *          @see cpu_error_t
1157  */
1158 int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename);
1159 
1160 /**
1161  * @brief Closes an open MSR driver
1162  *
1163  * This function unloads the MSR driver opened by cpu_msr_driver_open and
1164  * frees any resources associated with it.
1165  *
1166  * @param handle - a handle to the MSR reader driver, as created by cpu_msr_driver_open
1167  *
1168  * @returns zero if successful, and some negative number on error.
1169  *          The error message can be obtained by calling \ref cpuid_error.
1170  *          @see cpu_error_t
1171  */
1172 int cpu_msr_driver_close(struct msr_driver_t* handle);
1173 
1174 #ifdef __cplusplus
1175 } /* extern "C" */
1176 #endif
1177 
1178 
1179 /** @} */
1180 
1181 #endif /* __LIBCPUID_H__ */
1182