X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=arch%2Farch-x86-common.h;h=cbf66b8d04c18c63566dadff2d06e40a90fd8f69;hb=bc0c01e5d03d27e80d2a3b85ab21714bb6f32a19;hp=1e62354418c01d41e5bc2bf975617fbad314d315;hpb=2a988d8bcb447eb098fc382835cc507587c6ba66;p=fio.git diff --git a/arch/arch-x86-common.h b/arch/arch-x86-common.h index 1e623544..cbf66b8d 100644 --- a/arch/arch-x86-common.h +++ b/arch/arch-x86-common.h @@ -1,27 +1,25 @@ #ifndef FIO_ARCH_X86_COMMON #define FIO_ARCH_X86_COMMON -static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) +#include + +static inline void cpuid(unsigned int op, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) { - unsigned int id = *eax; - - asm("movl %4, %%eax;" - "cpuid;" - "movl %%eax, %0;" - "movl %%ebx, %1;" - "movl %%ecx, %2;" - "movl %%edx, %3;" - : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx) - : "r" (id) - : "eax", "ebx", "ecx", "edx"); + *eax = op; + *ecx = 0; + do_cpuid(eax, ebx, ecx, edx); } #define ARCH_HAVE_INIT + extern int tsc_reliable; -static inline int arch_init(char *envp[]) +extern int arch_random; + +static inline void arch_init_intel(unsigned int level) { - unsigned int eax, ebx, ecx, edx; + unsigned int eax, ebx, ecx = 0, edx; /* * Check for TSC @@ -29,15 +27,51 @@ static inline int arch_init(char *envp[]) eax = 1; do_cpuid(&eax, &ebx, &ecx, &edx); if (!(edx & (1U << 4))) - return 0; + return; /* * Check for constant rate and synced (across cores) TSC */ eax = 0x80000007; do_cpuid(&eax, &ebx, &ecx, &edx); - tsc_reliable = edx & (1U << 8); - return 0; + tsc_reliable = (edx & (1U << 8)) != 0; + + /* + * Check for FDRAND + */ + eax = 0x1; + do_cpuid(&eax, &ebx, &ecx, &edx); + arch_random = (ecx & (1U << 30)) != 0; +} + +static inline void arch_init_amd(unsigned int level) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + if (eax < 0x80000007) + return; + + cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + tsc_reliable = (edx & (1U << 8)) != 0; +} + +static inline void arch_init(char *envp[]) +{ + unsigned int level; + char str[13]; + + arch_random = tsc_reliable = 0; + + cpuid(0, &level, (unsigned int *) &str[0], + (unsigned int *) &str[8], + (unsigned int *) &str[4]); + + str[12] = '\0'; + if (!strcmp(str, "GenuineIntel")) + arch_init_intel(level); + else if (!strcmp(str, "AuthenticAMD")) + arch_init_amd(level); } #endif