[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