From: Ahmed Samy Date: Sun, 22 Sep 2013 07:42:15 +0000 (+0000) Subject: cpuid: add 2 new functions + some more tests X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=851a0d36a186d457e175116eadf4aa02c5686d02 cpuid: add 2 new functions + some more tests The new functions are: - get_cpu_type - get_cpu_type_string Also add more tests on how one would parse the low-level stuff. Signed-off-by: Ahmed Samy --- diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c index f25688e5..6f2c5a53 100644 --- a/ccan/cpuid/cpuid.c +++ b/ccan/cpuid/cpuid.c @@ -23,6 +23,7 @@ * http://en.wikipedia.org/wiki/CPUID */ #include +#include #include "cpuid.h" @@ -121,6 +122,54 @@ int cpuid_has_ext_feature(cpuextfeature_t extfeature) return 0; } +static const char *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" +}; + +cputype_t get_cpu_type(void) +{ + static cputype_t cputype; + if (cputype == CT_NONE) { + union { + char buf[12]; + uint32_t bufu32[3]; + } u; + uint32_t i; + + ___cpuid(CPU_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]); + u.buf[12] = '\0'; + + for (i = 0; i < sizeof(cpuids) / sizeof(cpuids[0]); ++i) { + if (strncmp(cpuids[i], u.buf, 12) == 0) { + cputype = (cputype_t)i; + break; + } + } + } + + return cputype; +} + +const char *get_cpu_type_string(const cputype_t cputype) +{ + return cpuids[(int)cputype]; +} + void cpuid(cpuid_t info, void *buf) { /* Sanity checks, make sure we're not trying to do something @@ -169,11 +218,10 @@ void cpuid(cpuid_t info, void *buf) case CPU_L1_CACHE_AND_TLB_IDS: break; case CPU_EXTENDED_L2_CACHE_FEATURES: - ubuf[0] = (ecx & 0xFF); /* Cache size */ - ubuf[1] = (ecx >> 12) & 0xF; /* Line size */ - ubuf[2] = (ecx >> 16) & 0xFFFF; /* Associativity */ + *ubuf = ecx; break; case CPU_ADV_POWER_MGT_INFO: + *ubuf = edx; break; case CPU_VIRT_PHYS_ADDR_SIZES: *ubuf = eax; diff --git a/ccan/cpuid/cpuid.h b/ccan/cpuid/cpuid.h index b9fab700..8c0b9b10 100644 --- a/ccan/cpuid/cpuid.h +++ b/ccan/cpuid/cpuid.h @@ -125,6 +125,43 @@ typedef enum cpuextfeature { CEF_XOP = 1 << 11 } cpuextfeature_t; +/** + * enum cputype - CPU type + * + * Warning, do not change this order or odd stuff may happen. + */ +typedef enum cputype { + CT_NONE, + CT_AMDK5, + CT_AMD, + CT_CENTAUR, + CT_CYRIX, + CT_INTEL, + CT_TRANSMETA, + CT_NATIONAL_SEMICONDUCTOR, + CT_NEXGEN, + CT_RISE, + CT_SIS, + CT_UMC, + CT_VIA, + CT_VORTEX, + CT_KVM +} cputype_t; + +/** + * get_cpu_type - Get CPU Type + * + * Returns the CPU Type as cputype_t. + */ +cputype_t get_cpu_type(void); + +/** + * get_cpu_type_string - Get CPU Type string + * + * Returns the CPU type string based off cputype_t. + */ +const char *get_cpu_type_string(const cputype_t cputype); + /** * cpuid_is_supported - test if the CPUID instruction is supported * diff --git a/ccan/cpuid/test/run.c b/ccan/cpuid/test/run.c index 65741f14..1f523e4a 100644 --- a/ccan/cpuid/test/run.c +++ b/ccan/cpuid/test/run.c @@ -1,6 +1,7 @@ #include "cpuid.h" #include +#include int main() { @@ -9,12 +10,6 @@ int main() return 1; } - printf ("MMX: %s\n", cpuid_has_mmx() ? "Yes" : "No"); - printf ("SSE: %s\n", cpuid_has_sse() ? "Yes" : "No"); - printf ("SSE2: %s\n", cpuid_has_sse2() ? "Yes" : "No"); - printf ("SSE3: %s\n", cpuid_has_sse3() ? "Yes" : "No"); - printf ("x64: %s\n", cpuid_has_x64() ? "Yes" : "No"); - char buf[128]; cpuid(CPU_VENDORID, buf); printf ("Vendor ID: %s\n", buf); @@ -26,22 +21,38 @@ int main() cpuid(CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED, &addr); printf ("Highest extended function supported: %#010x\n", addr); - int virtphys_size; - cpuid(CPU_VIRT_PHYS_ADDR_SIZES, &virtphys_size); - printf ("Virtual and physical address sizes: %d\n", virtphys_size); + union { + struct { + uint32_t phys_bits : 8; + uint32_t virt_bits : 8; + uint32_t reserved : 16; + }; + uint32_t w; + } s; + cpuid(CPU_VIRT_PHYS_ADDR_SIZES, &s.w); + printf ("Physical address size: %d\nVirtual: %d\n", s.phys_bits, s.virt_bits); int extfeatures[2]; cpuid(CPU_EXTENDED_PROC_INFO_FEATURE_BITS, extfeatures); printf ("Extended processor info and feature bits: %d %d\n", extfeatures[0], extfeatures[1]); - int l2features[3]; - cpuid(CPU_EXTENDED_L2_CACHE_FEATURES, l2features); + union { + struct { + uint32_t line_size : 8; + uint32_t reserved : 4; + uint32_t assoc : 4; + uint32_t cache_size : 16; + }; + + uint32_t w; + } l2c; + + cpuid(CPU_EXTENDED_L2_CACHE_FEATURES, &l2c.w); printf ("L2 Cache Size: %u KB\tLine Size: %u bytes\tAssociativity: %02xh\n", - l2features[0], l2features[1], l2features[2]); + l2c.cache_size, l2c.line_size, l2c.assoc); int invalid; cpuid(0x0ffffffUL, &invalid); printf ("Testing invalid: %#010x\n", invalid); return 0; } -