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 82253802Sdim#define bit_SSE 0x02000000 83253802Sdim#define bit_SSE2 0x04000000 84253802Sdim#define bit_SS 0x08000000 85253802Sdim#define bit_HTT 0x10000000 86253802Sdim#define bit_TM 0x20000000 87253802Sdim#define bit_PBE 0x80000000 88253802Sdim 89253802Sdim/* Features in %ebx for level 7 sub-leaf 0 */ 90253802Sdim#define bit_FSGSBASE 0x00000001 91253802Sdim#define bit_SMEP 0x00000080 92253802Sdim#define bit_ENH_MOVSB 0x00000200 93253802Sdim 94253802Sdim/* PIC on i386 uses %ebx, so preserve it. */ 95253802Sdim#if __i386__ 96253802Sdim#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ 97253802Sdim __asm(" pushl %%ebx\n" \ 98253802Sdim " cpuid\n" \ 99253802Sdim " mov %%ebx,%1\n" \ 100253802Sdim " popl %%ebx" \ 101253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 102253802Sdim : "0"(__level)) 103253802Sdim 104253802Sdim#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ 105253802Sdim __asm(" pushl %%ebx\n" \ 106253802Sdim " cpuid\n" \ 107253802Sdim " mov %%ebx,%1\n" \ 108253802Sdim " popl %%ebx" \ 109253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 110253802Sdim : "0"(__level), "2"(__count)) 111253802Sdim#else 112253802Sdim#define __cpuid(__level, __eax, __ebx, __ecx, __edx) \ 113253802Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 114253802Sdim : "0"(__level)) 115253802Sdim 116253802Sdim#define __cpuid_count(__level, __count, __eax, __ebx, __ecx, __edx) \ 117253802Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 118253802Sdim : "0"(__level), "2"(__count)) 119253802Sdim#endif 120253802Sdim 121249423Sdimstatic __inline int __get_cpuid (unsigned int __level, unsigned int *__eax, 122249423Sdim unsigned int *__ebx, unsigned int *__ecx, 123249423Sdim unsigned int *__edx) { 124253802Sdim __cpuid(__level, *__eax, *__ebx, *__ecx, *__edx); 125234287Sdim return 1; 126234287Sdim} 127253802Sdim 128253802Sdimstatic __inline int __get_cpuid_max (unsigned int __level, unsigned int *__sig) 129253802Sdim{ 130253802Sdim unsigned int __eax, __ebx, __ecx, __edx; 131253802Sdim#if __i386__ 132253802Sdim int __cpuid_supported; 133253802Sdim 134253802Sdim __asm(" pushfl\n" 135253802Sdim " popl %%eax\n" 136253802Sdim " movl %%eax,%%ecx\n" 137253802Sdim " xorl $0x00200000,%%eax\n" 138253802Sdim " pushl %%eax\n" 139253802Sdim " popfl\n" 140253802Sdim " pushfl\n" 141253802Sdim " popl %%eax\n" 142253802Sdim " movl $0,%0\n" 143253802Sdim " cmpl %%eax,%%ecx\n" 144253802Sdim " je 1f\n" 145253802Sdim " movl $1,%0\n" 146253802Sdim "1:" 147253802Sdim : "=r" (__cpuid_supported) : : "eax", "ecx"); 148253802Sdim if (!__cpuid_supported) 149253802Sdim return 0; 150253802Sdim#endif 151253802Sdim 152253802Sdim __cpuid(__level, __eax, __ebx, __ecx, __edx); 153253802Sdim if (__sig) 154253802Sdim *__sig = __ebx; 155253802Sdim return __eax; 156253802Sdim} 157