Commit | Line | Data |
---|---|---|
fa80feae JA |
1 | #ifndef FIO_ARCH_X86_COMMON |
2 | #define FIO_ARCH_X86_COMMON | |
3 | ||
7189c969 JA |
4 | #include <string.h> |
5 | ||
fa80feae JA |
6 | static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, |
7 | unsigned int *ecx, unsigned int *edx) | |
8 | { | |
267339ff JA |
9 | asm volatile("cpuid" |
10 | : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) | |
11 | : "0" (*eax), "2" (*ecx) | |
12 | : "memory"); | |
fa80feae JA |
13 | } |
14 | ||
7189c969 JA |
15 | static inline void cpuid(unsigned int op, |
16 | unsigned int *eax, unsigned int *ebx, | |
17 | unsigned int *ecx, unsigned int *edx) | |
18 | { | |
19 | *eax = op; | |
20 | *ecx = 0; | |
21 | do_cpuid(eax, ebx, ecx, edx); | |
22 | } | |
23 | ||
fa80feae | 24 | #define ARCH_HAVE_INIT |
7189c969 | 25 | |
fa80feae | 26 | extern int tsc_reliable; |
7189c969 JA |
27 | |
28 | static inline int arch_init_intel(unsigned int level) | |
fa80feae | 29 | { |
267339ff | 30 | unsigned int eax, ebx, ecx = 0, edx; |
fa80feae JA |
31 | |
32 | /* | |
33 | * Check for TSC | |
34 | */ | |
35 | eax = 1; | |
36 | do_cpuid(&eax, &ebx, &ecx, &edx); | |
37 | if (!(edx & (1U << 4))) | |
38 | return 0; | |
39 | ||
40 | /* | |
41 | * Check for constant rate and synced (across cores) TSC | |
42 | */ | |
43 | eax = 0x80000007; | |
44 | do_cpuid(&eax, &ebx, &ecx, &edx); | |
7189c969 JA |
45 | return edx & (1U << 8); |
46 | } | |
47 | ||
48 | static inline int arch_init_amd(unsigned int level) | |
49 | { | |
50 | unsigned int eax, ebx, ecx, edx; | |
51 | ||
52 | cpuid(0x80000000, &eax, &ebx, &ecx, &edx); | |
53 | if (eax < 0x80000007) | |
54 | return 0; | |
55 | ||
56 | cpuid(0x80000007, &eax, &ebx, &ecx, &edx); | |
57 | if (edx & (1 << 8)) | |
58 | return 1; | |
59 | ||
60 | return 0; | |
61 | } | |
62 | ||
63 | static inline int arch_init(char *envp[]) | |
64 | { | |
65 | unsigned int level; | |
66 | char str[12]; | |
67 | ||
68 | cpuid(0, &level, (unsigned int *) &str[0], | |
69 | (unsigned int *) &str[8], | |
70 | (unsigned int *) &str[4]); | |
71 | ||
72 | if (!strcmp(str, "GenuineIntel")) | |
73 | tsc_reliable = arch_init_intel(level); | |
74 | else if (!strcmp(str, "AuthenticAMD")) | |
75 | tsc_reliable = arch_init_amd(level); | |
76 | ||
fa80feae JA |
77 | return 0; |
78 | } | |
79 | ||
80 | #endif |