Merge branch 'master' of ssh://git.kernel.dk/data/git/fio
[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 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