X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fcpuid%2Fcpuid.c;h=4510def85b2dc0cb87fb0c780615a70da87fdd60;hb=0fd6bb104ac424b56326bd37de8b5057eb68243f;hp=d27441022d2bad386d4361a2ee5fbdff7113a402;hpb=dbbefec6973725d9a16c82747e0c7ce8e5e6c4f2;p=ccan diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c index d2744102..4510def8 100644 --- a/ccan/cpuid/cpuid.c +++ b/ccan/cpuid/cpuid.c @@ -37,7 +37,7 @@ enum { }; #ifndef _MSC_VER -static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +static void get_cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { __asm__( "xchg %%ebx, %%edi\n\t" /* 32bit PIC: Don't clobber ebx. */ @@ -50,7 +50,7 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, #else #include -static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) +static void get_cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { uint32_t registers[4]; __cpuid(registers, info); @@ -151,68 +151,80 @@ bool cpuid_test_feature(cpuid_t feature) return (feature <= cpuid_highest_ext_func_supported()); } -bool cpuid_has_ecxfeature(int feature) -{ - static uint32_t _ecx; - if (_ecx == 0) { #if defined(__GNUC__) || defined(__clang__) +static uint32_t fetch_ecx(uint32_t what) +{ + static uint32_t ecx; + if (ecx == 0) { asm volatile( "cpuid\n\t" - : "=c" (_ecx) - : "a" (CPUID_PROCINFO_AND_FEATUREBITS) + : "=c" (ecx) + : "a" (what) ); -#elif defined _MSC_VER + } + + return ecx; +} + +static uint32_t fetch_edx(uint32_t what) +{ + static uint32_t edx; + if (edx == 0) { + asm volatile( + "cpuid\n\t" + : "=d" (edx) + : "a" (what) + ); + } + + return edx; +} +#elif defined(_MSC_VER) +static uint32_t fetch_ecx(uint32_t what) +{ + static uint32_t _ecx; + if (_ecx == 0) { __asm { - mov eax, CPUID_PROCINFO_AND_FEATUREBITS + mov eax, what cpuid mov _ecx, ecx }; -#endif } - return (_ecx & feature) == feature; + return _ecx; } -bool cpuid_has_edxfeature(int feature) +static uint32_t fetch_edx(uint32_t what) { static uint32_t _edx; if (_edx == 0) { -#if defined(__GNUC__) || defined(__clang__) - asm volatile( - "cpuid\n\t" - : "=d" (_edx) - : "a" (CPUID_PROCINFO_AND_FEATUREBITS) - ); -#elif defined _MSC_VER __asm { - mov eax, CPUID_PROCINFO_AND_FEATUREBITS + mov eax, what cpuid mov _edx, edx }; -#endif } - return (_edx & feature) == feature; + return _edx; } +#endif -static const char *const cpuids[] = { - "Nooooooooone", - "AMDisbetter!", - "AuthenticAMD", - "CentaurHauls", - "CyrixInstead", - "GenuineIntel", - "TransmetaCPU", - "GeniuneTMx86", - "Geode by NSC", - "NexGenDriven", - "RiseRiseRise", - "SiS SiS SiS ", - "UMC UMC UMC ", - "VIA VIA VIA ", - "Vortex86 SoC", - "KVMKVMKVMKVM" -}; +#define DEFINE_FEATURE_FUNC(NAME, REGISTER, TYPE) \ + bool cpuid_has_##NAME(int feature) \ + { \ + static uint32_t REGISTER; \ + if (REGISTER == 0) \ + REGISTER = fetch_##REGISTER(TYPE); \ + return !!(REGISTER & feature); \ + } + +DEFINE_FEATURE_FUNC(ecxfeature, ecx, CPUID_PROCINFO_AND_FEATUREBITS) +DEFINE_FEATURE_FUNC(edxfeature, edx, CPUID_PROCINFO_AND_FEATUREBITS) + +DEFINE_FEATURE_FUNC(ecxfeature_ext, ecx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS) +DEFINE_FEATURE_FUNC(edxfeature_ext, edx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS) + +#undef DEFINE_FEATURE_FUNC cputype_t cpuid_get_cpu_type(void) { @@ -224,9 +236,9 @@ cputype_t cpuid_get_cpu_type(void) } u; uint32_t i; - ___cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]); - for (i = 0; i < sizeof(cpuids) / sizeof(cpuids[0]); ++i) { - if (strncmp(cpuids[i], u.buf, 12) == 0) { + get_cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]); + for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames[0]); ++i) { + if (strncmp(c_cpunames[i], u.buf, 12) == 0) { cputype = (cputype_t)i; break; } @@ -236,16 +248,6 @@ cputype_t cpuid_get_cpu_type(void) return cputype; } -bool cpuid_sprintf_cputype(const cputype_t cputype, char *buf) -{ - if (cputype == CT_NONE) - return false; - - memcpy(buf, cpuids[(int)cputype], 12); - buf[12] = '\0'; - return true; -} - uint32_t cpuid_highest_ext_func_supported(void) { static uint32_t highest; @@ -269,36 +271,36 @@ uint32_t cpuid_highest_ext_func_supported(void) return highest; } -void cpuid(cpuid_t info, uint32_t *buf) +void cpuid(cpuid_t request, uint32_t *buf) { /* Sanity checks, make sure we're not trying to do something * invalid or we are trying to get information that isn't supported * by the CPU. */ - if (info > CPUID_VIRT_PHYS_ADDR_SIZES || (info > CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED - && !cpuid_test_feature(info))) + if (request > CPUID_VIRT_PHYS_ADDR_SIZES || (request > CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED + && !cpuid_test_feature(request))) return; - if (info == CPUID_PROC_BRAND_STRING) { + if (request == CPUID_PROC_BRAND_STRING) { static char cached[48] = { 0 }; if (cached[0] == '\0') { - ___cpuid(CPUID_PROC_BRAND_STRING, &buf[0], &buf[1], &buf[2], &buf[3] ); - ___cpuid(CPUID_PROC_BRAND_STRING_INTERNAL0, &buf[4], &buf[5], &buf[6], &buf[7] ); - ___cpuid(CPUID_PROC_BRAND_STRING_INTERNAL1, &buf[8], &buf[9], &buf[10], &buf[11]); + get_cpuid(CPUID_PROC_BRAND_STRING, &buf[0], &buf[1], &buf[2], &buf[3] ); + get_cpuid(CPUID_PROC_BRAND_STRING_INTERNAL0, &buf[4], &buf[5], &buf[6], &buf[7] ); + get_cpuid(CPUID_PROC_BRAND_STRING_INTERNAL1, &buf[8], &buf[9], &buf[10], &buf[11]); memcpy(cached, buf, sizeof cached); } else buf = (uint32_t *)cached; return; - } else if (info == CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) { + } else if (request == CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) { *buf = cpuid_highest_ext_func_supported(); return; } uint32_t eax, ebx, ecx, edx; - ___cpuid(info, &eax, &ebx, &ecx, &edx); + get_cpuid(request, &eax, &ebx, &ecx, &edx); - switch (info) { + switch (request) { case CPUID_VENDORID: buf[0] = ebx; buf[1] = edx; @@ -366,32 +368,12 @@ void cpuid(cpuid_t info, uint32_t *buf) } } -bool cpuid_write_info(uint32_t info, uint32_t featureset, const char *outfile) +bool cpuid_write_info(uint32_t info, uint32_t featureset, FILE *file) { - FILE *file; - char filename[256]; - char cpu_information[64]; - - if (!cpuid_sprintf_cputype(cpuid_get_cpu_type(), cpu_information)) - return false; - char brand[48]; cpuid(CPUID_PROC_BRAND_STRING, (uint32_t *)brand); - cpu_information[12] = '_'; - memcpy(&cpu_information[13], brand, sizeof brand); - - if (!outfile) - strncpy(filename, cpu_information, sizeof cpu_information); - else - strncpy(filename, outfile, sizeof filename); - - file = fopen(filename, "w"); - if (!file) - return false; - - fprintf(file, "-- CPU Information for CPU: %s --\n\n", cpu_information); - + fprintf(file, "-- CPU Information for: %s_%s --\n\n", cpuid_get_name(), brand); if (info & CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) fprintf(file, "Highest extended function supported: %#010x\n\n", cpuid_highest_ext_func_supported()); @@ -673,7 +655,6 @@ bool cpuid_write_info(uint32_t info, uint32_t featureset, const char *outfile) } #undef YON - fclose(file); return true; }