[ccan] [PATCH 3/3] cpuid: add 2 new functions + some more tests

Peter Hutterer peter.hutterer at who-t.net
Mon Sep 23 16:03:47 EST 2013


On Sun, Sep 22, 2013 at 07:43:17AM +0000, Ahmed Samy wrote:
> The new functions are:
> - get_cpu_type
> - get_cpu_type_string
> 
> Also add more tests on how one would parse the low-level stuff.

ignoring the rest of the patch (which I don't have time to review atm,
sorry) but any reason these aren't prefixed with cpuid? it would namespace
better. this also goes for highest_ext_func_supported.

Cheers,
   Peter

>  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
> 
> _______________________________________________
> ccan mailing list
> ccan at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/ccan


More information about the ccan mailing list