[ccan] [PATCH 3/3] cpuid: add 2 new functions + some more tests
Ahmed Samy
f.fallen45 at gmail.com
Sun Sep 22 17:43:17 EST 2013
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 <f.fallen45 at gmail.com>
---
ccan/cpuid/cpuid.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++---
ccan/cpuid/cpuid.h | 37 +++++++++++++++++++++++++++++++++++
ccan/cpuid/test/run.c | 37 ++++++++++++++++++++++-------------
3 files changed, 112 insertions(+), 16 deletions(-)
diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c
index f25688e..6f2c5a5 100644
--- a/ccan/cpuid/cpuid.c
+++ b/ccan/cpuid/cpuid.c
@@ -23,6 +23,7 @@
* http://en.wikipedia.org/wiki/CPUID
*/
#include <stdint.h>
+#include <string.h>
#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 b9fab70..8c0b9b1 100644
--- a/ccan/cpuid/cpuid.h
+++ b/ccan/cpuid/cpuid.h
@@ -126,6 +126,43 @@ typedef enum cpuextfeature {
} 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
*
* CPUID is not supported by old CPUS.
diff --git a/ccan/cpuid/test/run.c b/ccan/cpuid/test/run.c
index 65741f1..1f523e4 100644
--- a/ccan/cpuid/test/run.c
+++ b/ccan/cpuid/test/run.c
@@ -1,6 +1,7 @@
#include "cpuid.h"
#include <stdio.h>
+#include <stdint.h>
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;
}
-
--
1.8.4
More information about the ccan
mailing list