mirror of
https://github.com/anrieff/libcpuid
synced 2025-10-03 11:01:30 +00:00
Fixed recognition of Core i7. It was required to obtain the extended CPU topology information from CPUID leaf 0xb, so 4 more ints are added to cpu_raw_data_t. This, in turn, breaks binary compatibility with version 0.1.0, so version is increased to 0.1.1 as well. The new CPUID serialization is backward- and forward-compatible with version 0.1.0, provided that the CPU doesn't have leaf 0xb. In some sense it might be viewed incompatible as well. Also added the guilty test case to the test stash
git-svn-id: https://svn.code.sf.net/p/libcpuid/code/HEAD/libcpuid@57 3b4be424-7ac5-41d7-8526-f4ddcb85d872
This commit is contained in:
parent
35a9c794b2
commit
59cf96984d
10 changed files with 170 additions and 14 deletions
10
configure.ac
10
configure.ac
|
@ -1,12 +1,18 @@
|
|||
AC_INIT([libcpuid CPU Identification library], [0.1.0], [libcpuid-devel@lists.sourceforge.net], [libcpuid])
|
||||
AC_INIT([libcpuid CPU Identification library], [0.1.1], [libcpuid-devel@lists.sourceforge.net], [libcpuid])
|
||||
AC_CONFIG_SRCDIR([libcpuid/libcpuid.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AM_INIT_AUTOMAKE([-Wall dist-bzip2 dist-zip foreign])
|
||||
|
||||
dnl Versioning scheme shamelessly copied from libexif.
|
||||
dnl Short walkthrough. C means CURRENT, A mean AGE, R means REVISION
|
||||
dnl 1) When you make a change that breaks binary compatibility, increment CURRENT, reset REVISION to 0 and:
|
||||
dnl 1.1) If the change doesn't remove interfaces, increment AGE, otherwise reset to 0.
|
||||
dnl 2) When you make just a source change that doesn't break binary compatibility, increment REVISION.
|
||||
dnl When you make a change that adds features, increment AGE, and set REVISION to 0
|
||||
dnl C:A:R
|
||||
dnl 10:0:0 Version 0.1.0
|
||||
LIBCPUID_CURRENT=10
|
||||
dnl 11:0:0 Version 0.1.1: four more fields to cpu_raw_data_t
|
||||
LIBCPUID_CURRENT=11
|
||||
LIBCPUID_AGE=0
|
||||
LIBCPUID_REVISION=0
|
||||
AC_SUBST([LIBCPUID_AGE])
|
||||
|
|
|
@ -5,7 +5,7 @@ all: libcpuid.lib
|
|||
ASM = ml64 /nologo
|
||||
CC = cl.exe /nologo /TC
|
||||
OPTFLAGS = /MT
|
||||
DEFINES = /D "VERSION=\"0.1.0\""
|
||||
DEFINES = /D "VERSION=\"0.1.1\""
|
||||
OBJECTS = masm-x64.obj asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_intel.obj rdtsc.obj
|
||||
|
||||
libcpuid.lib: $(OBJECTS)
|
||||
|
|
|
@ -12,7 +12,7 @@ all: libcpuid.lib
|
|||
|
||||
CC = cl.exe /nologo /TC
|
||||
OPTFLAGS = /MT
|
||||
DEFINES = /D "VERSION=\"0.1.0\""
|
||||
DEFINES = /D "VERSION=\"0.1.1\""
|
||||
OBJECTS = asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_intel.obj rdtsc.obj
|
||||
|
||||
libcpuid.lib: $(OBJECTS)
|
||||
|
|
|
@ -309,6 +309,12 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
|||
data->intel_fn4[i][2] = i;
|
||||
cpu_exec_cpuid_ext(data->intel_fn4[i]);
|
||||
}
|
||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
||||
memset(data->intel_fn11[i], 0, sizeof(data->intel_fn11[i]));
|
||||
data->intel_fn11[i][0] = 11;
|
||||
data->intel_fn11[i][2] = i;
|
||||
cpu_exec_cpuid_ext(data->intel_fn11[i]);
|
||||
}
|
||||
return set_error(ERR_OK);
|
||||
}
|
||||
|
||||
|
@ -337,6 +343,10 @@ int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
|
|||
fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->intel_fn4[i][0], data->intel_fn4[i][1],
|
||||
data->intel_fn4[i][2], data->intel_fn4[i][3]);
|
||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++)
|
||||
fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->intel_fn11[i][0], data->intel_fn11[i][1],
|
||||
data->intel_fn11[i][2], data->intel_fn11[i][3]);
|
||||
|
||||
if (strcmp(filename, ""))
|
||||
fclose(f);
|
||||
|
@ -384,6 +394,7 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename
|
|||
syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, 32, &recognized);
|
||||
syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, 32, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, 4, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, 4, &recognized);
|
||||
if (!syntax) {
|
||||
warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
|
||||
fclose(f);
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
* @File libcpuid.h
|
||||
* @Author Veselin Georgiev
|
||||
* @Date Oct 2008
|
||||
* @Version 0.1.0
|
||||
* @Version 0.1.1
|
||||
*
|
||||
* Version history:
|
||||
*
|
||||
* 0.1.0 (2008-10-15): initial adaptation from wxfractgui sources
|
||||
* 0.1.1 (2009-07-06): Added intel_fn11 fields to cpu_raw_data_t to handle
|
||||
* new processor topology enumeration required on Core i7
|
||||
*/
|
||||
|
||||
/** @mainpage A simple libcpuid introduction
|
||||
|
@ -100,6 +102,11 @@ struct cpu_raw_data_t {
|
|||
information: this contains the results of CPUID for eax = 4
|
||||
and ecx = 0, 1, ... */
|
||||
uint32_t intel_fn4[MAX_INTELFN4_LEVEL][4];
|
||||
|
||||
/** when the CPU is intel and it supports leaf 0Bh (Extended Topology
|
||||
enumeration leaf), this stores the result of CPUID with
|
||||
eax = 11 and ecx = 0, 1, 2... */
|
||||
uint32_t intel_fn11[MAX_INTELFN11_LEVEL][4];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -615,7 +622,7 @@ int cpu_clock(void);
|
|||
/**
|
||||
* @brief Returns the libcpuid version
|
||||
*
|
||||
* @returns the string representation of the libcpuid version, like "0.1.0"
|
||||
* @returns the string representation of the libcpuid version, like "0.1.1"
|
||||
*/
|
||||
const char* cpuid_lib_version(void);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;VERSION="\"0.1.0\"""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;VERSION="\"0.1.1\"""
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
|
@ -104,7 +104,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;VERSION="\"0.1.0\"""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;VERSION="\"0.1.1\"""
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
|
|
|
@ -38,5 +38,6 @@
|
|||
#define MAX_CPUID_LEVEL 32
|
||||
#define MAX_EXT_CPUID_LEVEL 32
|
||||
#define MAX_INTELFN4_LEVEL 4
|
||||
#define MAX_INTELFN11_LEVEL 4
|
||||
|
||||
#endif /* __LIBCPUID_CONSTANTS_H__ */
|
||||
|
|
|
@ -58,6 +58,7 @@ enum _intel_code_t {
|
|||
ATOM_DIAMONDVILLE,
|
||||
ATOM_DUALCORE,
|
||||
ATOM_SILVERTHORNE,
|
||||
CORE_Ix,
|
||||
};
|
||||
typedef enum _intel_code_t intel_code_t;
|
||||
|
||||
|
@ -236,8 +237,8 @@ const struct match_entry_t cpudb_intel[] = {
|
|||
{ 6, 7, -1, -1, 23, 1, 3072, QUAD_CORE , 0, "Yorkfield (Core 2 Quad) 3M"},
|
||||
{ 6, 7, -1, -1, 23, 1, 6144, QUAD_CORE , 0, "Yorkfield (Core 2 Quad) 6M"},
|
||||
|
||||
{ 6, 10, -1, -1, 26, 1, -1, NO_CODE , 0, "Intel Core i7" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, QUAD_CORE_HT , 0, "Bloomfield (Core i7)" },
|
||||
{ 6, 10, -1, -1, 26, 1, -1, CORE_Ix , 0, "Intel Core i7" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, CORE_Ix , 0, "Bloomfield (Core i7)" },
|
||||
|
||||
/* Core microarchitecture-based Xeons: */
|
||||
{ 6, 14, -1, -1, 14, 1, -1, XEON , 0, "Xeon LV" },
|
||||
|
@ -464,11 +465,38 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
|
|||
}
|
||||
}
|
||||
|
||||
static int decode_intel_extended_topology(struct cpu_raw_data_t* raw,
|
||||
struct cpu_id_t* data)
|
||||
{
|
||||
int i, level_type, num_smt = -1, num_core = -1;
|
||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
||||
level_type = (raw->intel_fn11[i][2] & 0xff00) >> 8;
|
||||
switch (level_type) {
|
||||
case 0x01:
|
||||
num_smt = raw->intel_fn11[i][1] & 0xffff;
|
||||
break;
|
||||
case 0x02:
|
||||
num_core = raw->intel_fn11[i][1] & 0xffff;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num_smt == -1 || num_core == -1) return 0;
|
||||
data->num_cores = num_core / num_smt;
|
||||
data->num_logical_cpus = num_core;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void decode_intel_number_of_cores(struct cpu_raw_data_t* raw,
|
||||
struct cpu_id_t* data)
|
||||
{
|
||||
int logical_cpus = -1, num_cores = -1;
|
||||
|
||||
if (raw->basic_cpuid[0][0] >= 11) {
|
||||
if (decode_intel_extended_topology(raw, data)) return;
|
||||
}
|
||||
|
||||
if (raw->basic_cpuid[0][0] >= 1) {
|
||||
logical_cpus = (raw->basic_cpuid[1][1] >> 16) & 0xff;
|
||||
if (raw->basic_cpuid[0][0] >= 4) {
|
||||
|
@ -491,9 +519,9 @@ static void decode_intel_number_of_cores(struct cpu_raw_data_t* raw,
|
|||
static intel_code_t get_brand_code(struct cpu_id_t* data)
|
||||
{
|
||||
intel_code_t code = NO_CODE;
|
||||
int i;
|
||||
int i, need_matchtable = 1;
|
||||
const char* bs = data->brand_str;
|
||||
const char* s;
|
||||
const char* s, *ixs;
|
||||
const struct { intel_code_t c; const char *search; } matchtable[] = {
|
||||
{ XEONMP, "Xeon MP" },
|
||||
{ XEONMP, "Xeon(TM) MP" },
|
||||
|
@ -512,11 +540,21 @@ static intel_code_t get_brand_code(struct cpu_id_t* data)
|
|||
};
|
||||
|
||||
if (strstr(bs, "Mobile")) {
|
||||
need_matchtable = 0;
|
||||
if (strstr(bs, "Celeron"))
|
||||
code = MOBILE_CELERON;
|
||||
else if (strstr(bs, "Pentium"))
|
||||
code = MOBILE_PENTIUM;
|
||||
} else {
|
||||
}
|
||||
ixs = strstr(bs, "Core(TM) i");
|
||||
if (ixs) {
|
||||
if (ixs[10] == '3' || ixs[10] == '5' || ixs[10] == '7') {
|
||||
/* Core i3, Core i5 or Core i7 */
|
||||
need_matchtable = 0;
|
||||
code = CORE_Ix;
|
||||
}
|
||||
}
|
||||
if (need_matchtable) {
|
||||
for (i = 0; i < COUNT_OF(matchtable); i++)
|
||||
if (strstr(bs, matchtable[i].search)) {
|
||||
code = matchtable[i].c;
|
||||
|
|
|
@ -11,7 +11,7 @@ if not len(args) in (3, 4):
|
|||
|
||||
rawdata = []
|
||||
for line in open(args[1], "rt").readlines():
|
||||
lookfor = ["basic_cpuid", "ext_cpuid", "intel_fn4"]
|
||||
lookfor = ["basic_cpuid", "ext_cpuid", "intel_fn4", "intel_fn11"]
|
||||
good = False
|
||||
for match in lookfor:
|
||||
if line.find(match) != -1:
|
||||
|
|
|
@ -2935,3 +2935,96 @@ intel_fn4[3]=00000000 00000000 00000000 00000000
|
|||
Yonah (Core Duo)
|
||||
fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pni monitor vmx est tm2 xtpr pdcm xd
|
||||
--------------------------------------------------------------------------------
|
||||
basic_cpuid[0]=0000000b 756e6547 6c65746e 49656e69
|
||||
basic_cpuid[1]=000106a4 03100800 0098e3bd bfebfbff
|
||||
basic_cpuid[2]=55035a01 00f0b2e4 00000000 09ca212c
|
||||
basic_cpuid[3]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[4]=1c004121 01c0003f 0000003f 00000000
|
||||
basic_cpuid[5]=00000040 00000040 00000003 00001120
|
||||
basic_cpuid[6]=00000003 00000002 00000001 00000000
|
||||
basic_cpuid[7]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[8]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[9]=00000000 00000000 00000000 00000000
|
||||
basic_cpuid[10]=07300403 00000040 00000000 00000603
|
||||
basic_cpuid[11]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[12]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[13]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[14]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[15]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[16]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[17]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[18]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[19]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[20]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[21]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[22]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[23]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[24]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[25]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[26]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[27]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[28]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[29]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[30]=00000001 00000002 00000100 00000003
|
||||
basic_cpuid[31]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[0]=80000008 00000000 00000000 00000000
|
||||
ext_cpuid[1]=00000000 00000000 00000001 28100000
|
||||
ext_cpuid[2]=65746e49 2952286c 726f4320 4d542865
|
||||
ext_cpuid[3]=37692029 55504320 20202020 20202020
|
||||
ext_cpuid[4]=30323920 20402020 37362e32 007a4847
|
||||
ext_cpuid[5]=00000000 00000000 00000000 00000000
|
||||
ext_cpuid[6]=00000000 00000000 01006040 00000000
|
||||
ext_cpuid[7]=00000000 00000000 00000000 00000100
|
||||
ext_cpuid[8]=00003024 00000000 00000000 00000000
|
||||
ext_cpuid[9]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[10]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[11]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[12]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[13]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[14]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[15]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[16]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[17]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[18]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[19]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[20]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[21]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[22]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[23]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[24]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[25]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[26]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[27]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[28]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[29]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[30]=00000001 00000002 00000100 00000003
|
||||
ext_cpuid[31]=00000001 00000002 00000100 00000003
|
||||
intel_fn4[0]=1c004121 01c0003f 0000003f 00000000
|
||||
intel_fn4[1]=1c004122 00c0003f 0000007f 00000000
|
||||
intel_fn4[2]=1c004143 01c0003f 000001ff 00000000
|
||||
intel_fn4[3]=1c03c163 03c0003f 00001fff 00000002
|
||||
intel_fn11[0]=00000001 00000002 00000100 00000003
|
||||
intel_fn11[1]=00000004 00000008 00000201 00000003
|
||||
intel_fn11[2]=00000000 00000000 00000002 00000003
|
||||
intel_fn11[3]=00000000 00000000 00000003 00000003
|
||||
--------------------------------------------------------------------------------
|
||||
6
|
||||
10
|
||||
4
|
||||
6
|
||||
26
|
||||
4
|
||||
8
|
||||
32
|
||||
32
|
||||
256
|
||||
8192
|
||||
8
|
||||
8
|
||||
16
|
||||
64
|
||||
64
|
||||
64
|
||||
Bloomfield (Core i7)
|
||||
fpu vme de pse tsc msr pae mce cx8 apic mtrr sep pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pni dts64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 xd popcnt lm lahf_lm
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue