c51c04c2d1b5f3a9958092ba05e468307e3cc42d
[fio.git] / arch / arch-x86-common.h
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 bool 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