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 extern int arch_random; 19 20 static inline void arch_init_intel(unsigned int level) 21 { 22 unsigned int eax, ebx, ecx = 0, edx; 23 24 /* 25 * Check for TSC 26 */ 27 eax = 1; 28 do_cpuid(&eax, &ebx, &ecx, &edx); 29 if (!(edx & (1U << 4))) 30 return; 31 32 /* 33 * Check for constant rate and synced (across cores) TSC 34 */ 35 eax = 0x80000007; 36 do_cpuid(&eax, &ebx, &ecx, &edx); 37 tsc_reliable = (edx & (1U << 8)) != 0; 38 39 /* 40 * Check for FDRAND 41 */ 42 eax = 0x1; 43 do_cpuid(&eax, &ebx, &ecx, &edx); 44 arch_random = (ecx & (1U << 30)) != 0; 45 } 46 47 static inline void arch_init_amd(unsigned int level) 48 { 49 unsigned int eax, ebx, ecx, edx; 50 51 cpuid(0x80000000, &eax, &ebx, &ecx, &edx); 52 if (eax < 0x80000007) 53 return; 54 55 cpuid(0x80000007, &eax, &ebx, &ecx, &edx); 56 tsc_reliable = (edx & (1U << 8)) != 0; 57 } 58 59 static inline void arch_init(char *envp[]) 60 { 61 unsigned int level; 62 char str[13]; 63 64 arch_random = tsc_reliable = 0; 65 66 cpuid(0, &level, (unsigned int *) &str[0], 67 (unsigned int *) &str[8], 68 (unsigned int *) &str[4]); 69 70 str[12] = '\0'; 71 if (!strcmp(str, "GenuineIntel")) 72 arch_init_intel(level); 73 else if (!strcmp(str, "AuthenticAMD")) 74 arch_init_amd(level); 75 } 76 77 #endif 78