• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef FIO_ARCH_X86_COMMON
2 #define FIO_ARCH_X86_COMMON
3 
4 #include <string.h>
5 
cpuid(unsigned int op,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)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 
arch_init_intel(unsigned int level)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 
arch_init_amd(unsigned int level)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 
arch_init(char * envp[])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