1
0
Fork 0
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:
Veselin Georgiev 2009-07-06 18:33:56 +00:00
commit 59cf96984d
10 changed files with 170 additions and 14 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -40,7 +40,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;VERSION=&quot;\&quot;0.1.0\&quot;&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;VERSION=&quot;\&quot;0.1.1\&quot;&quot;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -104,7 +104,7 @@
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;VERSION=&quot;\&quot;0.1.0\&quot;&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;VERSION=&quot;\&quot;0.1.1\&quot;&quot;"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"

View file

@ -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__ */

View file

@ -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;