cpuid: Minor improvements
[ccan] / ccan / cpuid / cpuid.h
1 /*
2  * Copyright (c) 2013 Ahmed Samy  <f.fallen45@gmail.com>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 #ifndef CCAN_CPUID_H
23 #define CCAN_CPUID_H
24
25 #include <stdbool.h>
26 #include <stdint.h>
27
28 /**
29  * enum cpuid - stuff to get information on from the CPU.
30  *
31  * This is used as a parameter in cpuid().
32  *
33  * CPU_VENDORID:
34  *      The CPU's Vendor ID.
35  *
36  * CPU_PROCINFO_AND_FEATUREBITS:
37  *      Processor information and feature bits (SSE, etc.).
38  *
39  * CPU_CACHE_AND_TLBD_INFO
40  *      Cache and TLBD Information.
41  *
42  * CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
43  *      Highest extended function supported address.
44  *      Can be like 0x80000008.
45  *
46  * CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
47  *      Extended processor information and feature bits (64bit etc.)
48  *
49  * CPU_PROC_BRAND_STRING:
50  *      The Processor's brand string.
51  *
52  * CPU_L1_CACHE_AND_TLB_IDS:
53  *      L1 Cache and TLB Identifications.
54  *
55  * CPU_EXTENDED_L2_CACHE_FEATURES:
56  *      Extended L2 Cache features.
57  *
58  * CPU_ADV_POWER_MGT_INFO:
59  *      Advaned power management information.
60  *
61  * CPU_VIRT_PHYS_ADDR_SIZES:
62  *      Virtual and physical address sizes.
63  */
64
65 typedef enum cpuid {
66         CPU_VENDORID                                    = 0,
67         CPU_PROCINFO_AND_FEATUREBITS                    = 1,
68         CPU_CACHE_AND_TLBD_INFO                         = 2,
69
70         CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED         = 0x80000000,
71         CPU_EXTENDED_PROC_INFO_FEATURE_BITS             = 0x80000001,
72         CPU_PROC_BRAND_STRING                           = 0x80000002, 
73         CPU_L1_CACHE_AND_TLB_IDS                        = 0x80000005,
74         CPU_EXTENDED_L2_CACHE_FEATURES                  = 0x80000006,
75         CPU_ADV_POWER_MGT_INFO                          = 0x80000007,
76         CPU_VIRT_PHYS_ADDR_SIZES                        = 0x80000008
77 } cpuid_t;
78
79 #define CF_MMX          0
80 #define CF_SSE          1
81 #define CF_SSE2         2
82 #define CF_SSE3         3
83 #define CF_FPU          4
84 #define CF_TSC          5
85 #define CF_MSR          6
86 #define CF_SSSE3        7
87 #define CF_AVX          8
88 #define CF_FMA          9
89
90 #define CEF_x64         10
91 #define CEF_FPU         11
92 #define CEF_DE          12
93 #define CEF_SYSCALLRET  13
94 #define CEF_CMOV        14
95 #define CEF_SSE4a       15
96 #define CEF_FMA4        16
97 #define CEF_XOP         17
98
99 typedef enum cputype {
100         CT_NONE,
101         CT_AMDK5,
102         CT_AMD,
103         CT_CENTAUR,
104         CT_CYRIX,
105         CT_INTEL,
106         CT_TRANSMETA,
107         CT_NATIONAL_SEMICONDUCTOR,
108         CT_NEXGEN,
109         CT_RISE,
110         CT_SIS,
111         CT_UMC,
112         CT_VIA,
113         CT_VORTEX,
114         CT_KVM
115 } cputype_t;
116
117 #if defined(__i386__) || defined(__i386) || defined(__x86_64) \
118         || defined(_M_AMD64) || defined(__M_X64)
119
120 /**
121  * cpuid_get_cpu_type - Get CPU Type
122  *
123  * Returns the CPU Type as cputype_t.
124  *
125  * See also: cpuid_get_cpu_type_string()
126  */
127 cputype_t cpuid_get_cpu_type(void);
128
129 /**
130  * cpuid_get_cpu_type_string - Get CPU Type string
131  *
132  * Returns the CPU type string based off cputype_t.
133  */
134 const char *cpuid_get_cpu_type_string(const cputype_t cputype);
135
136 /**
137  * cpuid_is_supported - test if the CPUID instruction is supported
138  *
139  * CPUID is not supported by old CPUS.
140  *
141  * Returns true if the cpuid instruction is supported, false otherwise.
142  *
143  * See also: cpuid()
144  */
145 bool cpuid_is_supported(void);
146
147 /**
148  * cpuid_highest_ext_func_supported - Get the highest extended function supported
149  *
150  *
151  * Returns the highest extended function supported.
152  *
153  * This is the same as calling:
154  *      cpuid(CPU_HIGHEST_EEXTENDED_FUNCTION_SUPPORTED, &highest);
155  *
156  * This is made visible to the linker because it's easier to call it
157  * instead of calling cpuid with less type-checking.  cpuid calls this.
158  *
159  * See also: cpuid()
160  */
161 uint32_t cpuid_highest_ext_func_supported(void);
162
163 /**
164  * cpuid - Get Some information from the CPU.
165  *
166  * This function expects buf to be a valid pointer to a string/int/...
167  * depending on the requested information.
168  *
169  * For CPU_VENDOR_ID:
170  *      Returns a string into buf.
171  *
172  * For CPU_PROCINFO_AND_FEATUREBITS:
173  *      buf[0]:
174  *              - 3:0 - Stepping
175  *              - 7:4 - Model
176  *              - 11:8 - Family
177  *              - 13:12 - Processor Type
178  *              - 19:16 - Extended Model
179  *              - 27:20 - Extended family
180  *      buf[1] and buf[2]:
181  *              Feature flags
182  *      buf[3]:
183  *              Additional feature information.
184  *
185  * For CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
186  *      Returns the highest supported function in *buf (expects an integer ofc)
187  *
188  * For CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
189  *      Returns them in buf[0] and buf[1].
190  *
191  * For CPU_VIRT_PHYS_ADDR_SIZES:
192  *      Returns it as an integer in *buf.
193  *
194  * For CPU_PROC_BRAND_STRING:
195  *      Have a char array with at least 48 bytes assigned to it.
196  *
197  * If an invalid flag has been passed a 0xbaadf00d is returned in *buf.
198  */
199 void cpuid(cpuid_t info, uint32_t *buf);
200
201 /**
202  * cpuid_test_feature - Test if @feature is available
203  *
204  * Returns true if feature is supported, false otherwise.
205  *
206  * The feature parameter must be >= CPU_EXTENDED_PROC_INFO_FEATURE_BITS
207  *  and <= CPU_VIRT_PHYS_ADDR_SIZES.
208  */
209 bool cpuid_test_feature(cpuid_t feature);
210
211 /**
212  * cpuid_has_feature - Test if @feature is supported
213  *
214  * Test if the CPU supports MMX/SSE* etc.
215  * For the extended parameter, usually you want to pass it as
216  * false if you're not passing CEF_*.
217  *
218  * For more information about the CPU extended features, have a look
219  * at:
220  *      http://en.wikipedia.org/wiki/CPUID
221  *
222  * Returns true if the feature is available, false otherwise.
223  */
224 #define cpuid_has_mmx()         cpuid_has_feature(CF_MMX,       false)
225 #define cpuid_has_sse()         cpuid_has_feature(CF_SSE,       false)
226 #define cpuid_has_sse2()        cpuid_has_feature(CF_SSE2,      false)
227 #define cpuid_has_sse3()        cpuid_has_feature(CF_SSE3,      false)
228 #define cpuid_has_ssse3()       cpuid_has_feature(CF_SSSE3,     false)
229 #define cpuid_has_avx()         cpuid_has_feature(CF_AVX,       false)
230 #define cpuid_has_fma()         cpuid_has_feature(CF_FMA,       false)
231 #define cpuid_has_x64()         cpuid_has_feature(CEF_x64,      true)
232 #define cpuid_has_sse4a()       cpuid_has_feature(CEF_SSE4a,    true)
233 #define cpuid_has_fma4()        cpuid_has_feature(CEF_FMA4,     true)
234 #define cpuid_has_xop()         cpuid_has_feature(CEF_XOP,      true)
235 bool cpuid_has_feature(int feature, bool extended);
236
237 #else
238
239 #define cpuid_get_cpu_type()                    BUILD_ASSERT_OR_ZERO(0)
240 #define cpuid_get_cpu_type_string()             BUILD_ASSERT_OR_ZERO(0)
241
242 #define cpuid_is_supported()                    BUILD_ASSERT_OR_ZERO(0)
243 #define cpuid(info, buf)                        BUILD_ASSERT_OR_ZERO(0)
244
245 #define cpuid_highest_ext_func_supported()      BUILD_ASSERT_OR_ZERO(0)
246 #define cpuid_test_feature(feature)             BUILD_ASSERT_OR_ZERO(0)
247 #define cpuid_has_feature(feature, ext)         BUILD_ASSERT_OR_ZERO(0)
248
249 #endif
250 #endif
251