Home | History | Annotate | Download | only in arch
      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