X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=arch%2Farch-x86-common.h;h=78fd40c03d40c71f9f915bf615e1cc06dce6a97a;hp=d533d22d536bce1ffbc162a1cdb50af1ae4f3848;hb=7189c969816dbea1c4c73209e61332b75cf882c7;hpb=5bd5f71a3e54950fb4bee64c7ad5edc67e40b8c8 diff --git a/arch/arch-x86-common.h b/arch/arch-x86-common.h index d533d22d..78fd40c0 100644 --- a/arch/arch-x86-common.h +++ b/arch/arch-x86-common.h @@ -1,6 +1,8 @@ #ifndef FIO_ARCH_X86_COMMON #define FIO_ARCH_X86_COMMON +#include + static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -10,9 +12,20 @@ static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, : "memory"); } +static inline void cpuid(unsigned int op, + unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *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[]) + +static inline int arch_init_intel(unsigned int level) { unsigned int eax, ebx, ecx = 0, edx; @@ -29,7 +42,38 @@ static inline int arch_init(char *envp[]) */ eax = 0x80000007; do_cpuid(&eax, &ebx, &ecx, &edx); - tsc_reliable = edx & (1U << 8); + return edx & (1U << 8); +} + +static inline int arch_init_amd(unsigned int level) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + if (eax < 0x80000007) + return 0; + + cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + if (edx & (1 << 8)) + return 1; + + return 0; +} + +static inline int arch_init(char *envp[]) +{ + unsigned int level; + char str[12]; + + cpuid(0, &level, (unsigned int *) &str[0], + (unsigned int *) &str[8], + (unsigned int *) &str[4]); + + if (!strcmp(str, "GenuineIntel")) + tsc_reliable = arch_init_intel(level); + else if (!strcmp(str, "AuthenticAMD")) + tsc_reliable = arch_init_amd(level); + return 0; }