Commit 851a0d36 authored by Ahmed Samy's avatar Ahmed Samy

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: default avatarAhmed Samy <f.fallen45@gmail.com>
parent 7684b602
......@@ -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;
......
......@@ -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
*
......
#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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment