1 #ifndef FIO_ARCH_X86_COMMON 2 #define FIO_ARCH_X86_COMMON 3 4 #include <string.h> 5 6 static inline void cpuid(unsigned int op, 7 unsigned int *eax, unsigned int *ebx, 8 unsigned int *ecx, unsigned int *edx) 9 { 10 *eax = op; 11 *ecx = 0; 12 do_cpuid(eax, ebx, ecx, edx); 13 } 14 15 #define ARCH_HAVE_INIT 16 17 extern int tsc_reliable; 18 19 static inline int arch_init_intel(unsigned int level) 20 { 21 unsigned int eax, ebx, ecx = 0, edx; 22 23 /* 24 * Check for TSC 25 */ 26 eax = 1; 27 do_cpuid(&eax, &ebx, &ecx, &edx); 28 if (!(edx & (1U << 4))) 29 return 0; 30 31 /* 32 * Check for constant rate and synced (across cores) TSC 33 */ 34 eax = 0x80000007; 35 do_cpuid(&eax, &ebx, &ecx, &edx); 36 return edx & (1U << 8); 37 } 38 39 static inline int arch_init_amd(unsigned int level) 40 { 41 unsigned int eax, ebx, ecx, edx; 42 43 cpuid(0x80000000, &eax, &ebx, &ecx, &edx); 44 if (eax < 0x80000007) 45 return 0; 46 47 cpuid(0x80000007, &eax, &ebx, &ecx, &edx); 48 if (edx & (1 << 8)) 49 return 1; 50 51 return 0; 52 } 53 54 static inline int arch_init(char *envp[]) 55 { 56 unsigned int level; 57 char str[13]; 58 59 cpuid(0, &level, (unsigned int *) &str[0], 60 (unsigned int *) &str[8], 61 (unsigned int *) &str[4]); 62 63 str[12] = '\0'; 64 if (!strcmp(str, "GenuineIntel")) 65 tsc_reliable = arch_init_intel(level); 66 else if (!strcmp(str, "AuthenticAMD")) 67 tsc_reliable = arch_init_amd(level); 68 69 return 0; 70 } 71 72 #endif 73