[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