cpuid.h revision 259498
1234287Sdim/*===---- cpuid.h - X86 cpu model detection --------------------------------=== 2234287Sdim * 3234287Sdim * Permission is hereby granted, free of charge, to any person obtaining a copy 4234287Sdim * of this software and associated documentation files (the "Software"), to deal 5234287Sdim * in the Software without restriction, including without limitation the rights 6234287Sdim * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7234287Sdim * copies of the Software, and to permit persons to whom the Software is 8234287Sdim * furnished to do so, subject to the following conditions: 9234287Sdim * 10234287Sdim * The above copyright notice and this permission notice shall be included in 11234287Sdim * all copies or substantial portions of the Software. 12234287Sdim * 13234287Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14234287Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15234287Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16234287Sdim * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17234287Sdim * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18234287Sdim * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19234287Sdim * THE SOFTWARE. 20234287Sdim * 21234287Sdim *===-----------------------------------------------------------------------=== 22234287Sdim */ 23234287Sdim 24234287Sdim#if !(__x86_64__ || __i386__) 25234287Sdim#error this header is for x86 only 26234287Sdim#endif 27234287Sdim 28253802Sdim/* Features in %ecx for level 1 */ 29253802Sdim#define bit_SSE3 0x00000001 30253802Sdim#define bit_PCLMULQDQ 0x00000002 31253802Sdim#define bit_DTES64 0x00000004 32253802Sdim#define bit_MONITOR 0x00000008 33253802Sdim#define bit_DSCPL 0x00000010 34253802Sdim#define bit_VMX 0x00000020 35253802Sdim#define bit_SMX 0x00000040 36253802Sdim#define bit_EIST 0x00000080 37253802Sdim#define bit_TM2 0x00000100 38253802Sdim#define bit_SSSE3 0x00000200 39253802Sdim#define bit_CNXTID 0x00000400 40253802Sdim#define bit_FMA 0x00001000 41253802Sdim#define bit_CMPXCHG16B 0x00002000 42253802Sdim#define bit_xTPR 0x00004000 43253802Sdim#define bit_PDCM 0x00008000 44253802Sdim#define bit_PCID 0x00020000 45253802Sdim#define bit_DCA 0x00040000 46253802Sdim#define bit_SSE41 0x00080000 47253802Sdim#define bit_SSE42 0x00100000 48253802Sdim#define bit_x2APIC 0x00200000 49253802Sdim#define bit_MOVBE 0x00400000 50253802Sdim#define bit_POPCNT 0x00800000 51253802Sdim#define bit_TSCDeadline 0x01000000 52253802Sdim#define bit_AESNI 0x02000000 53253802Sdim#define bit_XSAVE 0x04000000 54253802Sdim#define bit_OSXSAVE 0x08000000 55253802Sdim#define bit_AVX 0x10000000 56253802Sdim#define bit_RDRAND 0x40000000 57253802Sdim 58253802Sdim/* Features in %edx for level 1 */ 59253802Sdim#define bit_FPU 0x00000001 60253802Sdim#define bit_VME 0x00000002 61253802Sdim#define bit_DE 0x00000004 62253802Sdim#define bit_PSE 0x00000008 63253802Sdim#define bit_TSC 0x00000010 64253802Sdim#define bit_MSR 0x00000020 65253802Sdim#define bit_PAE 0x00000040 66253802Sdim#define bit_MCE 0x00000080 67253802Sdim#define bit_CX8 0x00000100 68253802Sdim#define bit_APIC 0x00000200 69253802Sdim#define bit_SEP 0x00000800 70253802Sdim#define bit_MTRR 0x00001000 71253802Sdim#define bit_PGE 0x00002000 72253802Sdim#define bit_MCA 0x00004000 73253802Sdim#define bit_CMOV 0x00008000 74253802Sdim#define bit_PAT 0x00010000 75253802Sdim#define bit_PSE36 0x00020000 76253802Sdim#define bit_PSN 0x00040000 77253802Sdim#define bit_CLFSH 0x00080000 78253802Sdim#define bit_DS 0x00200000 79253802Sdim#define bit_ACPI 0x00400000 80253802Sdim#define bit_MMX 0x00800000 81253802Sdim#define bit_FXSR 0x01000000 82259498Sdim#define bit_FXSAVE bit_FXSR /* for gcc compat */ 83253802Sdim#define bit_SSE 0x02000000 84253802Sdim#define bit_SSE2 0x04000000 85253802Sdim#define bit_SS 0x08000000 86253802Sdim#define bit_HTT 0x10000000 87253802Sdim#define bit_TM 0x20000000 88253802Sdim#define bit_PBE 0x80000000 89253802Sdim 90253802Sdim/* Features in %ebx for level 7 sub-leaf 0 */ 91253802Sdim#define bit_FSGSBASE 0x00000001 92253802Sdim#define bit_SMEP 0x00000080 93253802Sdim#define bit_ENH_MOVSB 0x00000200 94253802Sdim 95253802Sdim/* PIC on i386 uses %ebx, so preserve it. */ 96253802Sdim#if __i386__ 97253802Sdim#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ 98253802Sdim __asm(" pushl %%ebx\n" \ 99253802Sdim " cpuid\n" \ 100253802Sdim " mov %%ebx,%1\n" \ 101253802Sdim " popl %%ebx" \ 102253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 103253802Sdim : "0"(__level)) 104253802Sdim 105253802Sdim#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ 106253802Sdim __asm(" pushl %%ebx\n" \ 107253802Sdim " cpuid\n" \ 108253802Sdim " mov %%ebx,%1\n" \ 109253802Sdim " popl %%ebx" \ 110253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 111253802Sdim : "0"(__level), "2"(__count)) 112253802Sdim#else 113253802Sdim#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ 114253802Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 115253802Sdim : "0"(__level)) 116253802Sdim 117253802Sdim#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ 118253802Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 119253802Sdim : "0"(__level), "2"(__count)) 120253802Sdim#endif 121253802Sdim 122249423Sdimstatic __inline int __get_cpuid (unsigned int __level, unsigned int *__eax, 123249423Sdim unsigned int *__ebx, unsigned int *__ecx, 124249423Sdim unsigned int *__edx) { 125253802Sdim __cpuid(__level, *__eax, *__ebx, *__ecx, *__edx); 126234287Sdim return 1; 127234287Sdim} 128253802Sdim 129253802Sdimstatic __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig) 130253802Sdim{ 131253802Sdim unsigned int __eax, __ebx, __ecx, __edx; 132253802Sdim#if __i386__ 133253802Sdim int __cpuid_supported; 134253802Sdim 135253802Sdim __asm(" pushfl\n" 136253802Sdim " popl %%eax\n" 137253802Sdim " movl %%eax,%%ecx\n" 138253802Sdim " xorl $0x00200000,%%eax\n" 139253802Sdim " pushl %%eax\n" 140253802Sdim " popfl\n" 141253802Sdim " pushfl\n" 142253802Sdim " popl %%eax\n" 143253802Sdim " movl $0,%0\n" 144253802Sdim " cmpl %%eax,%%ecx\n" 145253802Sdim " je 1f\n" 146253802Sdim " movl $1,%0\n" 147253802Sdim "1:" 148253802Sdim : "=r" (__cpuid_supported) : : "eax", "ecx"); 149253802Sdim if (!__cpuid_supported) 150253802Sdim return 0; 151253802Sdim#endif 152253802Sdim 153253802Sdim __cpuid(__level, __eax, __ebx, __ecx, __edx); 154253802Sdim if (__sig) 155253802Sdim *__sig = __ebx; 156253802Sdim return __eax; 157253802Sdim} 158