1 /* Public domain. */ 2 3 #ifndef _ASM_CPUFEATURE_H 4 #define _ASM_CPUFEATURE_H 5 6 #if defined(__amd64__) || defined(__i386__) 7 8 #include <sys/param.h> 9 10 #define X86_FEATURE_CLFLUSH 1 11 #define X86_FEATURE_XMM4_1 2 12 #define X86_FEATURE_PAT 3 13 #define X86_FEATURE_HYPERVISOR 4 14 15 static inline bool static_cpu_has(uint16_t f)16static_cpu_has(uint16_t f) 17 { 18 switch (f) { 19 case X86_FEATURE_XMM4_1: 20 return (cpu_ecxfeature & CPUIDECX_SSE41) != 0; 21 #ifdef __amd64__ 22 case X86_FEATURE_CLFLUSH: 23 case X86_FEATURE_PAT: 24 return true; 25 #else 26 case X86_FEATURE_CLFLUSH: 27 return curcpu()->ci_cflushsz != 0; 28 case X86_FEATURE_PAT: 29 return (curcpu()->ci_feature_flags & CPUID_PAT) != 0; 30 #endif 31 case X86_FEATURE_HYPERVISOR: 32 return (cpu_ecxfeature & CPUIDECX_HV) != 0; 33 default: 34 return false; 35 } 36 } 37 38 static inline bool pat_enabled(void)39pat_enabled(void) 40 { 41 return static_cpu_has(X86_FEATURE_PAT); 42 } 43 44 #define boot_cpu_has(x) static_cpu_has(x) 45 46 static inline void clflushopt(volatile void * addr)47clflushopt(volatile void *addr) 48 { 49 if (curcpu()->ci_feature_sefflags_ebx & SEFF0EBX_CLFLUSHOPT) 50 __asm volatile("clflushopt %0" : "+m" (*(volatile char *)addr)); 51 else 52 __asm volatile("clflush %0" : "+m" (*(volatile char *)addr)); 53 } 54 55 #endif 56 57 #endif 58