Reduce libcpuid size.
This commit is contained in:
parent
b11f95d248
commit
da02e9a3a2
8 changed files with 28 additions and 1767 deletions
438
src/3rdparty/libcpuid/cpuid_main.c
vendored
438
src/3rdparty/libcpuid/cpuid_main.c
vendored
|
@ -46,11 +46,6 @@ int set_error(cpu_error_t err)
|
|||
return (int) err;
|
||||
}
|
||||
|
||||
static void raw_data_t_constructor(struct cpu_raw_data_t* raw)
|
||||
{
|
||||
memset(raw, 0, sizeof(struct cpu_raw_data_t));
|
||||
}
|
||||
|
||||
static void cpu_id_t_constructor(struct cpu_id_t* id)
|
||||
{
|
||||
memset(id, 0, sizeof(struct cpu_id_t));
|
||||
|
@ -60,29 +55,6 @@ static void cpu_id_t_constructor(struct cpu_id_t* id)
|
|||
id->sse_size = -1;
|
||||
}
|
||||
|
||||
static int parse_token(const char* expected_token, const char *token,
|
||||
const char *value, uint32_t array[][4], int limit, int *recognized)
|
||||
{
|
||||
char format[32];
|
||||
int veax, vebx, vecx, vedx;
|
||||
int index;
|
||||
|
||||
if (*recognized) return 1; /* already recognized */
|
||||
if (strncmp(token, expected_token, strlen(expected_token))) return 1; /* not what we search for */
|
||||
sprintf(format, "%s[%%d]", expected_token);
|
||||
*recognized = 1;
|
||||
if (1 == sscanf(token, format, &index) && index >=0 && index < limit) {
|
||||
if (4 == sscanf(value, "%x%x%x%x", &veax, &vebx, &vecx, &vedx)) {
|
||||
array[index][0] = veax;
|
||||
array[index][1] = vebx;
|
||||
array[index][2] = vecx;
|
||||
array[index][3] = vedx;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get_total_cpus() system specific code: uses OS routines to determine total number of CPUs */
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h>
|
||||
|
@ -249,42 +221,42 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da
|
|||
|
||||
static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str)
|
||||
{
|
||||
int i;
|
||||
cpu_vendor_t vendor = VENDOR_UNKNOWN;
|
||||
const struct { cpu_vendor_t vendor; char match[16]; }
|
||||
matchtable[NUM_CPU_VENDORS] = {
|
||||
/* source: http://www.sandpile.org/ia32/cpuid.htm */
|
||||
{ VENDOR_INTEL , "GenuineIntel" },
|
||||
{ VENDOR_AMD , "AuthenticAMD" },
|
||||
{ VENDOR_CYRIX , "CyrixInstead" },
|
||||
{ VENDOR_NEXGEN , "NexGenDriven" },
|
||||
{ VENDOR_TRANSMETA , "GenuineTMx86" },
|
||||
{ VENDOR_UMC , "UMC UMC UMC " },
|
||||
{ VENDOR_CENTAUR , "CentaurHauls" },
|
||||
{ VENDOR_RISE , "RiseRiseRise" },
|
||||
{ VENDOR_SIS , "SiS SiS SiS " },
|
||||
{ VENDOR_NSC , "Geode by NSC" },
|
||||
};
|
||||
int i;
|
||||
cpu_vendor_t vendor = VENDOR_UNKNOWN;
|
||||
const struct { cpu_vendor_t vendor; char match[16]; }
|
||||
matchtable[NUM_CPU_VENDORS] = {
|
||||
/* source: http://www.sandpile.org/ia32/cpuid.htm */
|
||||
{ VENDOR_INTEL , "GenuineIntel" },
|
||||
{ VENDOR_AMD , "AuthenticAMD" },
|
||||
{ VENDOR_CYRIX , "CyrixInstead" },
|
||||
{ VENDOR_NEXGEN , "NexGenDriven" },
|
||||
{ VENDOR_TRANSMETA , "GenuineTMx86" },
|
||||
{ VENDOR_UMC , "UMC UMC UMC " },
|
||||
{ VENDOR_CENTAUR , "CentaurHauls" },
|
||||
{ VENDOR_RISE , "RiseRiseRise" },
|
||||
{ VENDOR_SIS , "SiS SiS SiS " },
|
||||
{ VENDOR_NSC , "Geode by NSC" },
|
||||
};
|
||||
|
||||
memcpy(vendor_str + 0, &raw_vendor[1], 4);
|
||||
memcpy(vendor_str + 4, &raw_vendor[3], 4);
|
||||
memcpy(vendor_str + 8, &raw_vendor[2], 4);
|
||||
vendor_str[12] = 0;
|
||||
memcpy(vendor_str + 0, &raw_vendor[1], 4);
|
||||
memcpy(vendor_str + 4, &raw_vendor[3], 4);
|
||||
memcpy(vendor_str + 8, &raw_vendor[2], 4);
|
||||
vendor_str[12] = 0;
|
||||
|
||||
/* Determine vendor: */
|
||||
for (i = 0; i < NUM_CPU_VENDORS; i++)
|
||||
if (!strcmp(vendor_str, matchtable[i].match)) {
|
||||
vendor = matchtable[i].vendor;
|
||||
break;
|
||||
}
|
||||
return vendor;
|
||||
/* Determine vendor: */
|
||||
for (i = 0; i < NUM_CPU_VENDORS; i++)
|
||||
if (!strcmp(vendor_str, matchtable[i].match)) {
|
||||
vendor = matchtable[i].vendor;
|
||||
break;
|
||||
}
|
||||
return vendor;
|
||||
}
|
||||
|
||||
static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||
{
|
||||
int i, j, basic, xmodel, xfamily, ext;
|
||||
char brandstr[64] = {0};
|
||||
data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str);
|
||||
data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str);
|
||||
|
||||
if (data->vendor == VENDOR_UNKNOWN)
|
||||
return set_error(ERR_CPU_UNKN);
|
||||
|
@ -320,27 +292,6 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat
|
|||
return set_error(ERR_OK);
|
||||
}
|
||||
|
||||
static void make_list_from_string(const char* csv, struct cpu_list_t* list)
|
||||
{
|
||||
int i, n, l, last;
|
||||
l = (int) strlen(csv);
|
||||
n = 0;
|
||||
for (i = 0; i < l; i++) if (csv[i] == ',') n++;
|
||||
n++;
|
||||
list->num_entries = n;
|
||||
list->names = (char**) malloc(sizeof(char*) * n);
|
||||
last = -1;
|
||||
n = 0;
|
||||
for (i = 0; i <= l; i++) if (i == l || csv[i] == ',') {
|
||||
list->names[n] = (char*) malloc(i - last);
|
||||
memcpy(list->names[n], &csv[last + 1], i - last - 1);
|
||||
list->names[n][i - last - 1] = '\0';
|
||||
n++;
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Interface: */
|
||||
|
||||
int cpuid_get_total_cpus(void)
|
||||
|
@ -401,107 +352,6 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
|||
return set_error(ERR_OK);
|
||||
}
|
||||
|
||||
int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
|
||||
if (!strcmp(filename, ""))
|
||||
f = stdout;
|
||||
else
|
||||
f = fopen(filename, "wt");
|
||||
if (!f) return set_error(ERR_OPEN);
|
||||
|
||||
fprintf(f, "version=%s\n", VERSION);
|
||||
for (i = 0; i < MAX_CPUID_LEVEL; i++)
|
||||
fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->basic_cpuid[i][0], data->basic_cpuid[i][1],
|
||||
data->basic_cpuid[i][2], data->basic_cpuid[i][3]);
|
||||
for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++)
|
||||
fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->ext_cpuid[i][0], data->ext_cpuid[i][1],
|
||||
data->ext_cpuid[i][2], data->ext_cpuid[i][3]);
|
||||
for (i = 0; i < MAX_INTELFN4_LEVEL; i++)
|
||||
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]);
|
||||
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++)
|
||||
fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->intel_fn12h[i][0], data->intel_fn12h[i][1],
|
||||
data->intel_fn12h[i][2], data->intel_fn12h[i][3]);
|
||||
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++)
|
||||
fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i,
|
||||
data->intel_fn14h[i][0], data->intel_fn14h[i][1],
|
||||
data->intel_fn14h[i][2], data->intel_fn14h[i][3]);
|
||||
|
||||
if (strcmp(filename, ""))
|
||||
fclose(f);
|
||||
return set_error(ERR_OK);
|
||||
}
|
||||
|
||||
int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
|
||||
{
|
||||
int i, len;
|
||||
char line[100];
|
||||
char token[100];
|
||||
char *value;
|
||||
int syntax;
|
||||
int cur_line = 0;
|
||||
int recognized;
|
||||
FILE *f;
|
||||
|
||||
raw_data_t_constructor(data);
|
||||
|
||||
if (!strcmp(filename, ""))
|
||||
f = stdin;
|
||||
else
|
||||
f = fopen(filename, "rt");
|
||||
if (!f) return set_error(ERR_OPEN);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
++cur_line;
|
||||
len = (int) strlen(line);
|
||||
if (len < 2) continue;
|
||||
if (line[len - 1] == '\n')
|
||||
line[--len] = '\0';
|
||||
for (i = 0; i < len && line[i] != '='; i++)
|
||||
if (i >= len && i < 1 && len - i - 1 <= 0) {
|
||||
fclose(f);
|
||||
return set_error(ERR_BADFMT);
|
||||
}
|
||||
strncpy(token, line, i);
|
||||
token[i] = '\0';
|
||||
value = &line[i + 1];
|
||||
/* try to recognize the line */
|
||||
recognized = 0;
|
||||
if (!strcmp(token, "version") || !strcmp(token, "build_date")) {
|
||||
recognized = 1;
|
||||
}
|
||||
syntax = 1;
|
||||
syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized);
|
||||
syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized);
|
||||
syntax = syntax && parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized);
|
||||
if (!syntax) {
|
||||
warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
|
||||
fclose(f);
|
||||
return set_error(ERR_BADFMT);
|
||||
}
|
||||
if (!recognized) {
|
||||
warnf("Warning: %s:%d not understood!\n", filename, cur_line);
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(filename, ""))
|
||||
fclose(f);
|
||||
return set_error(ERR_OK);
|
||||
}
|
||||
|
||||
int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
||||
{
|
||||
int r;
|
||||
|
@ -533,239 +383,7 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|||
return cpu_ident_internal(raw, data, &throwaway);
|
||||
}
|
||||
|
||||
const char* cpu_feature_str(cpu_feature_t feature)
|
||||
{
|
||||
const struct { cpu_feature_t feature; const char* name; }
|
||||
matchtable[] = {
|
||||
{ CPU_FEATURE_FPU, "fpu" },
|
||||
{ CPU_FEATURE_VME, "vme" },
|
||||
{ CPU_FEATURE_DE, "de" },
|
||||
{ CPU_FEATURE_PSE, "pse" },
|
||||
{ CPU_FEATURE_TSC, "tsc" },
|
||||
{ CPU_FEATURE_MSR, "msr" },
|
||||
{ CPU_FEATURE_PAE, "pae" },
|
||||
{ CPU_FEATURE_MCE, "mce" },
|
||||
{ CPU_FEATURE_CX8, "cx8" },
|
||||
{ CPU_FEATURE_APIC, "apic" },
|
||||
{ CPU_FEATURE_MTRR, "mtrr" },
|
||||
{ CPU_FEATURE_SEP, "sep" },
|
||||
{ CPU_FEATURE_PGE, "pge" },
|
||||
{ CPU_FEATURE_MCA, "mca" },
|
||||
{ CPU_FEATURE_CMOV, "cmov" },
|
||||
{ CPU_FEATURE_PAT, "pat" },
|
||||
{ CPU_FEATURE_PSE36, "pse36" },
|
||||
{ CPU_FEATURE_PN, "pn" },
|
||||
{ CPU_FEATURE_CLFLUSH, "clflush" },
|
||||
{ CPU_FEATURE_DTS, "dts" },
|
||||
{ CPU_FEATURE_ACPI, "acpi" },
|
||||
{ CPU_FEATURE_MMX, "mmx" },
|
||||
{ CPU_FEATURE_FXSR, "fxsr" },
|
||||
{ CPU_FEATURE_SSE, "sse" },
|
||||
{ CPU_FEATURE_SSE2, "sse2" },
|
||||
{ CPU_FEATURE_SS, "ss" },
|
||||
{ CPU_FEATURE_HT, "ht" },
|
||||
{ CPU_FEATURE_TM, "tm" },
|
||||
{ CPU_FEATURE_IA64, "ia64" },
|
||||
{ CPU_FEATURE_PBE, "pbe" },
|
||||
{ CPU_FEATURE_PNI, "pni" },
|
||||
{ CPU_FEATURE_PCLMUL, "pclmul" },
|
||||
{ CPU_FEATURE_DTS64, "dts64" },
|
||||
{ CPU_FEATURE_MONITOR, "monitor" },
|
||||
{ CPU_FEATURE_DS_CPL, "ds_cpl" },
|
||||
{ CPU_FEATURE_VMX, "vmx" },
|
||||
{ CPU_FEATURE_SMX, "smx" },
|
||||
{ CPU_FEATURE_EST, "est" },
|
||||
{ CPU_FEATURE_TM2, "tm2" },
|
||||
{ CPU_FEATURE_SSSE3, "ssse3" },
|
||||
{ CPU_FEATURE_CID, "cid" },
|
||||
{ CPU_FEATURE_CX16, "cx16" },
|
||||
{ CPU_FEATURE_XTPR, "xtpr" },
|
||||
{ CPU_FEATURE_PDCM, "pdcm" },
|
||||
{ CPU_FEATURE_DCA, "dca" },
|
||||
{ CPU_FEATURE_SSE4_1, "sse4_1" },
|
||||
{ CPU_FEATURE_SSE4_2, "sse4_2" },
|
||||
{ CPU_FEATURE_SYSCALL, "syscall" },
|
||||
{ CPU_FEATURE_XD, "xd" },
|
||||
{ CPU_FEATURE_X2APIC, "x2apic"},
|
||||
{ CPU_FEATURE_MOVBE, "movbe" },
|
||||
{ CPU_FEATURE_POPCNT, "popcnt" },
|
||||
{ CPU_FEATURE_AES, "aes" },
|
||||
{ CPU_FEATURE_XSAVE, "xsave" },
|
||||
{ CPU_FEATURE_OSXSAVE, "osxsave" },
|
||||
{ CPU_FEATURE_AVX, "avx" },
|
||||
{ CPU_FEATURE_MMXEXT, "mmxext" },
|
||||
{ CPU_FEATURE_3DNOW, "3dnow" },
|
||||
{ CPU_FEATURE_3DNOWEXT, "3dnowext" },
|
||||
{ CPU_FEATURE_NX, "nx" },
|
||||
{ CPU_FEATURE_FXSR_OPT, "fxsr_opt" },
|
||||
{ CPU_FEATURE_RDTSCP, "rdtscp" },
|
||||
{ CPU_FEATURE_LM, "lm" },
|
||||
{ CPU_FEATURE_LAHF_LM, "lahf_lm" },
|
||||
{ CPU_FEATURE_CMP_LEGACY, "cmp_legacy" },
|
||||
{ CPU_FEATURE_SVM, "svm" },
|
||||
{ CPU_FEATURE_SSE4A, "sse4a" },
|
||||
{ CPU_FEATURE_MISALIGNSSE, "misalignsse" },
|
||||
{ CPU_FEATURE_ABM, "abm" },
|
||||
{ CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" },
|
||||
{ CPU_FEATURE_OSVW, "osvw" },
|
||||
{ CPU_FEATURE_IBS, "ibs" },
|
||||
{ CPU_FEATURE_SSE5, "sse5" },
|
||||
{ CPU_FEATURE_SKINIT, "skinit" },
|
||||
{ CPU_FEATURE_WDT, "wdt" },
|
||||
{ CPU_FEATURE_TS, "ts" },
|
||||
{ CPU_FEATURE_FID, "fid" },
|
||||
{ CPU_FEATURE_VID, "vid" },
|
||||
{ CPU_FEATURE_TTP, "ttp" },
|
||||
{ CPU_FEATURE_TM_AMD, "tm_amd" },
|
||||
{ CPU_FEATURE_STC, "stc" },
|
||||
{ CPU_FEATURE_100MHZSTEPS, "100mhzsteps" },
|
||||
{ CPU_FEATURE_HWPSTATE, "hwpstate" },
|
||||
{ CPU_FEATURE_CONSTANT_TSC, "constant_tsc" },
|
||||
{ CPU_FEATURE_XOP, "xop" },
|
||||
{ CPU_FEATURE_FMA3, "fma3" },
|
||||
{ CPU_FEATURE_FMA4, "fma4" },
|
||||
{ CPU_FEATURE_TBM, "tbm" },
|
||||
{ CPU_FEATURE_F16C, "f16c" },
|
||||
{ CPU_FEATURE_RDRAND, "rdrand" },
|
||||
{ CPU_FEATURE_CPB, "cpb" },
|
||||
{ CPU_FEATURE_APERFMPERF, "aperfmperf" },
|
||||
{ CPU_FEATURE_PFI, "pfi" },
|
||||
{ CPU_FEATURE_PA, "pa" },
|
||||
{ CPU_FEATURE_AVX2, "avx2" },
|
||||
{ CPU_FEATURE_BMI1, "bmi1" },
|
||||
{ CPU_FEATURE_BMI2, "bmi2" },
|
||||
{ CPU_FEATURE_HLE, "hle" },
|
||||
{ CPU_FEATURE_RTM, "rtm" },
|
||||
{ CPU_FEATURE_AVX512F, "avx512f" },
|
||||
{ CPU_FEATURE_AVX512DQ, "avx512dq" },
|
||||
{ CPU_FEATURE_AVX512PF, "avx512pf" },
|
||||
{ CPU_FEATURE_AVX512ER, "avx512er" },
|
||||
{ CPU_FEATURE_AVX512CD, "avx512cd" },
|
||||
{ CPU_FEATURE_SHA_NI, "sha_ni" },
|
||||
{ CPU_FEATURE_AVX512BW, "avx512bw" },
|
||||
{ CPU_FEATURE_AVX512VL, "avx512vl" },
|
||||
{ CPU_FEATURE_SGX, "sgx" },
|
||||
{ CPU_FEATURE_RDSEED, "rdseed" },
|
||||
{ CPU_FEATURE_ADX, "adx" },
|
||||
};
|
||||
unsigned i, n = COUNT_OF(matchtable);
|
||||
if (n != NUM_CPU_FEATURES) {
|
||||
warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n");
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
if (matchtable[i].feature == feature)
|
||||
return matchtable[i].name;
|
||||
return "";
|
||||
}
|
||||
|
||||
const char* cpuid_error(void)
|
||||
{
|
||||
const struct { cpu_error_t error; const char *description; }
|
||||
matchtable[] = {
|
||||
{ ERR_OK , "No error"},
|
||||
{ ERR_NO_CPUID , "CPUID instruction is not supported"},
|
||||
{ ERR_NO_RDTSC , "RDTSC instruction is not supported"},
|
||||
{ ERR_NO_MEM , "Memory allocation failed"},
|
||||
{ ERR_OPEN , "File open operation failed"},
|
||||
{ ERR_BADFMT , "Bad file format"},
|
||||
{ ERR_NOT_IMP , "Not implemented"},
|
||||
{ ERR_CPU_UNKN , "Unsupported processor"},
|
||||
{ ERR_NO_RDMSR , "RDMSR instruction is not supported"},
|
||||
{ ERR_NO_DRIVER, "RDMSR driver error (generic)"},
|
||||
{ ERR_NO_PERMS , "No permissions to install RDMSR driver"},
|
||||
{ ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"},
|
||||
{ ERR_HANDLE , "Bad handle"},
|
||||
{ ERR_INVMSR , "Invalid MSR"},
|
||||
{ ERR_INVCNB , "Invalid core number"},
|
||||
{ ERR_HANDLE_R , "Error on handle read"},
|
||||
{ ERR_INVRANGE , "Invalid given range"},
|
||||
};
|
||||
unsigned i;
|
||||
for (i = 0; i < COUNT_OF(matchtable); i++)
|
||||
if (_libcpiud_errno == matchtable[i].error)
|
||||
return matchtable[i].description;
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
|
||||
const char* cpuid_lib_version(void)
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn)
|
||||
{
|
||||
libcpuid_warn_fn_t ret = _warn_fun;
|
||||
_warn_fun = new_fn;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpuid_set_verbosiness_level(int level)
|
||||
{
|
||||
_current_verboselevel = level;
|
||||
}
|
||||
|
||||
cpu_vendor_t cpuid_get_vendor(void)
|
||||
{
|
||||
static cpu_vendor_t vendor = VENDOR_UNKNOWN;
|
||||
uint32_t raw_vendor[4];
|
||||
char vendor_str[VENDOR_STR_MAX];
|
||||
|
||||
if(vendor == VENDOR_UNKNOWN) {
|
||||
if (!cpuid_present())
|
||||
set_error(ERR_NO_CPUID);
|
||||
else {
|
||||
cpu_exec_cpuid(0, raw_vendor);
|
||||
vendor = cpuid_vendor_identify(raw_vendor, vendor_str);
|
||||
}
|
||||
}
|
||||
return vendor;
|
||||
}
|
||||
|
||||
void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list)
|
||||
{
|
||||
switch (vendor) {
|
||||
case VENDOR_INTEL:
|
||||
cpuid_get_list_intel(list);
|
||||
break;
|
||||
case VENDOR_AMD:
|
||||
cpuid_get_list_amd(list);
|
||||
break;
|
||||
case VENDOR_CYRIX:
|
||||
make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list);
|
||||
break;
|
||||
case VENDOR_NEXGEN:
|
||||
make_list_from_string("Nx586", list);
|
||||
break;
|
||||
case VENDOR_TRANSMETA:
|
||||
make_list_from_string("Crusoe,Efficeon", list);
|
||||
break;
|
||||
case VENDOR_UMC:
|
||||
make_list_from_string("UMC x86 CPU", list);
|
||||
break;
|
||||
case VENDOR_CENTAUR:
|
||||
make_list_from_string("VIA C3,VIA C7,VIA Nano", list);
|
||||
break;
|
||||
case VENDOR_RISE:
|
||||
make_list_from_string("Rise mP6", list);
|
||||
break;
|
||||
case VENDOR_SIS:
|
||||
make_list_from_string("SiS mP6", list);
|
||||
break;
|
||||
case VENDOR_NSC:
|
||||
make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list);
|
||||
break;
|
||||
default:
|
||||
warnf("Unknown vendor passed to cpuid_get_cpu_list()\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cpuid_free_cpu_list(struct cpu_list_t* list)
|
||||
{
|
||||
int i;
|
||||
if (list->num_entries <= 0) return;
|
||||
for (i = 0; i < list->num_entries; i++)
|
||||
free(list->names[i]);
|
||||
free(list->names);
|
||||
}
|
||||
|
|
473
src/3rdparty/libcpuid/libcpuid.h
vendored
473
src/3rdparty/libcpuid/libcpuid.h
vendored
|
@ -610,39 +610,6 @@ void cpu_exec_cpuid_ext(uint32_t* regs);
|
|||
*/
|
||||
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
|
||||
|
||||
/**
|
||||
* @brief Writes the raw CPUID data to a text file
|
||||
* @param data - a pointer to cpu_raw_data_t structure
|
||||
* @param filename - the path of the file, where the serialized data should be
|
||||
* written. If empty, stdout will be used.
|
||||
* @note This is intended primarily for debugging. On some processor, which is
|
||||
* not currently supported or not completely recognized by cpu_identify,
|
||||
* one can still successfully get the raw data and write it to a file.
|
||||
* libcpuid developers can later import this file and debug the detection
|
||||
* code as if running on the actual hardware.
|
||||
* The file is simple text format of "something=value" pairs. Version info
|
||||
* is also written, but the format is not intended to be neither backward-
|
||||
* nor forward compatible.
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Reads raw CPUID data from file
|
||||
* @param data - a pointer to cpu_raw_data_t structure. The deserialized data will
|
||||
* be written here.
|
||||
* @param filename - the path of the file, containing the serialized raw data.
|
||||
* If empty, stdin will be used.
|
||||
* @note This function may fail, if the file is created by different version of
|
||||
* the library. Also, see the notes on cpuid_serialize_raw_data.
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Identifies the CPU
|
||||
* @param raw - Input - a pointer to the raw CPUID data, which is obtained
|
||||
|
@ -668,222 +635,6 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename
|
|||
*/
|
||||
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
|
||||
|
||||
/**
|
||||
* @brief Returns the short textual representation of a CPU flag
|
||||
* @param feature - the feature, whose textual representation is wanted.
|
||||
* @returns a constant string like "fpu", "tsc", "sse2", etc.
|
||||
* @note the names of the returned flags are compatible with those from
|
||||
* /proc/cpuinfo in Linux, with the exception of `tm_amd'
|
||||
*/
|
||||
const char* cpu_feature_str(cpu_feature_t feature);
|
||||
|
||||
/**
|
||||
* @brief Returns textual description of the last error
|
||||
*
|
||||
* libcpuid stores an `errno'-style error status, whose description
|
||||
* can be obtained with this function.
|
||||
* @note This function is not thread-safe
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
const char* cpuid_error(void);
|
||||
|
||||
/**
|
||||
* @brief Executes RDTSC
|
||||
*
|
||||
* The RDTSC (ReaD Time Stamp Counter) instruction gives access to an
|
||||
* internal 64-bit counter, which usually increments at each clock cycle.
|
||||
* This can be used for various timing routines, and as a very precise
|
||||
* clock source. It is set to zero on system startup. Beware that may not
|
||||
* increment at the same frequency as the CPU. Consecutive calls of RDTSC
|
||||
* are, however, guaranteed to return monotonically-increasing values.
|
||||
*
|
||||
* @param result - a pointer to a 64-bit unsigned integer, where the TSC value
|
||||
* will be stored
|
||||
*
|
||||
* @note If 100% compatibility is a concern, you must first check if the
|
||||
* RDTSC instruction is present (if it is not, your program will crash
|
||||
* with "invalid opcode" exception). Only some very old processors (i486,
|
||||
* early AMD K5 and some Cyrix CPUs) lack that instruction - they should
|
||||
* have become exceedingly rare these days. To verify RDTSC presence,
|
||||
* run cpu_identify() and check flags[CPU_FEATURE_TSC].
|
||||
*
|
||||
* @note The monotonically increasing nature of the TSC may be violated
|
||||
* on SMP systems, if their TSC clocks run at different rate. If the OS
|
||||
* doesn't account for that, the TSC drift may become arbitrary large.
|
||||
*/
|
||||
void cpu_rdtsc(uint64_t* result);
|
||||
|
||||
/**
|
||||
* @brief Store TSC and timing info
|
||||
*
|
||||
* This function stores the current TSC value and current
|
||||
* time info from a precise OS-specific clock source in the cpu_mark_t
|
||||
* structure. The sys_clock field contains time with microsecond resolution.
|
||||
* The values can later be used to measure time intervals, number of clocks,
|
||||
* FPU frequency, etc.
|
||||
* @see cpu_rdtsc
|
||||
*
|
||||
* @param mark [out] - a pointer to a cpu_mark_t structure
|
||||
*/
|
||||
void cpu_tsc_mark(struct cpu_mark_t* mark);
|
||||
|
||||
/**
|
||||
* @brief Calculate TSC and timing difference
|
||||
*
|
||||
* @param mark - input/output: a pointer to a cpu_mark_t sturcture, which has
|
||||
* already been initialized by cpu_tsc_mark. The difference in
|
||||
* TSC and time will be written here.
|
||||
*
|
||||
* This function calculates the TSC and time difference, by obtaining the
|
||||
* current TSC and timing values and subtracting the contents of the `mark'
|
||||
* structure from them. Results are written in the same structure.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* ...
|
||||
* struct cpu_mark_t mark;
|
||||
* cpu_tsc_mark(&mark);
|
||||
* foo();
|
||||
* cpu_tsc_unmark(&mark);
|
||||
* printf("Foo finished. Executed in %llu cycles and %llu usecs\n",
|
||||
* mark.tsc, mark.sys_clock);
|
||||
* ...
|
||||
* @endcode
|
||||
*/
|
||||
void cpu_tsc_unmark(struct cpu_mark_t* mark);
|
||||
|
||||
/**
|
||||
* @brief Calculates the CPU clock
|
||||
*
|
||||
* @param mark - pointer to a cpu_mark_t structure, which has been initialized
|
||||
* with cpu_tsc_mark and later `stopped' with cpu_tsc_unmark.
|
||||
*
|
||||
* @note For reliable results, the marked time interval should be at least about
|
||||
* 10 ms.
|
||||
*
|
||||
* @returns the CPU clock frequency, in MHz. Due to measurement error, it will
|
||||
* differ from the true value in a few least-significant bits. Accuracy depends
|
||||
* on the timing interval - the more, the better. If the timing interval is
|
||||
* insufficient, the result is -1. Also, see the comment on cpu_clock_measure
|
||||
* for additional issues and pitfalls in using RDTSC for CPU frequency
|
||||
* measurements.
|
||||
*/
|
||||
int cpu_clock_by_mark(struct cpu_mark_t* mark);
|
||||
|
||||
/**
|
||||
* @brief Returns the CPU clock, as reported by the OS
|
||||
*
|
||||
* This function uses OS-specific functions to obtain the CPU clock. It may
|
||||
* differ from the true clock for several reasons:<br><br>
|
||||
*
|
||||
* i) The CPU might be in some power saving state, while the OS reports its
|
||||
* full-power frequency, or vice-versa.<br>
|
||||
* ii) In some cases you can raise or lower the CPU frequency with overclocking
|
||||
* utilities and the OS will not notice.
|
||||
*
|
||||
* @returns the CPU clock frequency in MHz. If the OS is not (yet) supported
|
||||
* or lacks the necessary reporting machinery, the return value is -1
|
||||
*/
|
||||
int cpu_clock_by_os(void);
|
||||
|
||||
/**
|
||||
* @brief Measure the CPU clock frequency
|
||||
*
|
||||
* @param millis - How much time to waste in the busy-wait cycle. In millisecs.
|
||||
* Useful values 10 - 1000
|
||||
* @param quad_check - Do a more thorough measurement if nonzero
|
||||
* (see the explanation).
|
||||
*
|
||||
* The function performs a busy-wait cycle for the given time and calculates
|
||||
* the CPU frequency by the difference of the TSC values. The accuracy of the
|
||||
* calculation depends on the length of the busy-wait cycle: more is better,
|
||||
* but 100ms should be enough for most purposes.
|
||||
*
|
||||
* While this will calculate the CPU frequency correctly in most cases, there are
|
||||
* several reasons why it might be incorrect:<br>
|
||||
*
|
||||
* i) RDTSC doesn't guarantee it will run at the same clock as the CPU.
|
||||
* Apparently there aren't CPUs at the moment, but still, there's no
|
||||
* guarantee.<br>
|
||||
* ii) The CPU might be in a low-frequency power saving mode, and the CPU
|
||||
* might be switched to higher frequency at any time. If this happens
|
||||
* during the measurement, the result can be anywhere between the
|
||||
* low and high frequencies. Also, if you're interested in the
|
||||
* high frequency value only, this function might return the low one
|
||||
* instead.<br>
|
||||
* iii) On SMP systems exhibiting TSC drift (see \ref cpu_rdtsc)
|
||||
*
|
||||
* the quad_check option will run four consecutive measurements and
|
||||
* then return the average of the two most-consistent results. The total
|
||||
* runtime of the function will still be `millis' - consider using
|
||||
* a bit more time for the timing interval.
|
||||
*
|
||||
* Finally, for benchmarking / CPU intensive applications, the best strategy is
|
||||
* to use the cpu_tsc_mark() / cpu_tsc_unmark() / cpu_clock_by_mark() method.
|
||||
* Begin by mark()-ing about one second after application startup (allowing the
|
||||
* power-saving manager to kick in and rise the frequency during that time),
|
||||
* then unmark() just before application finishing. The result will most
|
||||
* acurately represent at what frequency your app was running.
|
||||
*
|
||||
* @returns the CPU clock frequency in MHz (within some measurement error
|
||||
* margin). If RDTSC is not supported, the result is -1.
|
||||
*/
|
||||
int cpu_clock_measure(int millis, int quad_check);
|
||||
|
||||
/**
|
||||
* @brief Measure the CPU clock frequency using instruction-counting
|
||||
*
|
||||
* @param millis - how much time to allocate for each run, in milliseconds
|
||||
* @param runs - how many runs to perform
|
||||
*
|
||||
* The function performs a busy-wait cycle using a known number of "heavy" (SSE)
|
||||
* instructions. These instructions run at (more or less guaranteed) 1 IPC rate,
|
||||
* so by running a busy loop for a fixed amount of time, and measuring the
|
||||
* amount of instructions done, the CPU clock is accurately measured.
|
||||
*
|
||||
* Of course, this function is still affected by the power-saving schemes, so
|
||||
* the warnings as of cpu_clock_measure() still apply. However, this function is
|
||||
* immune to problems with detection, related to the Intel Nehalem's "Turbo"
|
||||
* mode, where the internal clock is raised, but the RDTSC rate is unaffected.
|
||||
*
|
||||
* The function will run for about (millis * runs) milliseconds.
|
||||
* You can make only a single busy-wait run (runs == 1); however, this can
|
||||
* be affected by task scheduling (which will break the counting), so allowing
|
||||
* more than one run is recommended. As run length is not imperative for
|
||||
* accurate readings (e.g., 50ms is sufficient), you can afford a lot of short
|
||||
* runs, e.g. 10 runs of 50ms or 20 runs of 25ms.
|
||||
*
|
||||
* Recommended values - millis = 50, runs = 4. For more robustness,
|
||||
* increase the number of runs.
|
||||
*
|
||||
* NOTE: on Bulldozer and later CPUs, the busy-wait cycle runs at 1.4 IPC, thus
|
||||
* the results are skewed. This is corrected internally by dividing the resulting
|
||||
* value by 1.4.
|
||||
* However, this only occurs if the thread is executed on a single CMT
|
||||
* module - if there are other threads competing for resources, the results are
|
||||
* unpredictable. Make sure you run cpu_clock_by_ic() on a CPU that is free from
|
||||
* competing threads, or if there are such threads, they shouldn't exceed the
|
||||
* number of modules. On a Bulldozer X8, that means 4 threads.
|
||||
*
|
||||
* @returns the CPU clock frequency in MHz (within some measurement error
|
||||
* margin). If SSE is not supported, the result is -1. If the input parameters
|
||||
* are incorrect, or some other internal fault is detected, the result is -2.
|
||||
*/
|
||||
int cpu_clock_by_ic(int millis, int runs);
|
||||
|
||||
/**
|
||||
* @brief Get the CPU clock frequency (all-in-one method)
|
||||
*
|
||||
* This is an all-in-one method for getting the CPU clock frequency.
|
||||
* It tries to use the OS for that. If the OS doesn't have this info, it
|
||||
* uses cpu_clock_measure with 200ms time interval and quadruple checking.
|
||||
*
|
||||
* @returns the CPU clock frequency in MHz. If every possible method fails,
|
||||
* the result is -1.
|
||||
*/
|
||||
int cpu_clock(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief The return value of cpuid_get_epc().
|
||||
* @details
|
||||
|
@ -916,230 +667,6 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
|
|||
*/
|
||||
const char* cpuid_lib_version(void);
|
||||
|
||||
typedef void (*libcpuid_warn_fn_t) (const char *msg);
|
||||
/**
|
||||
* @brief Sets the warning print function
|
||||
*
|
||||
* In some cases, the internal libcpuid machinery would like to emit useful
|
||||
* debug warnings. By default, these warnings are written to stderr. However,
|
||||
* you can set a custom function that will receive those warnings.
|
||||
*
|
||||
* @param warn_fun - the warning function you want to set. If NULL, warnings
|
||||
* are disabled. The function takes const char* argument.
|
||||
*
|
||||
* @returns the current warning function. You can use the return value to
|
||||
* keep the previous warning function and restore it at your discretion.
|
||||
*/
|
||||
libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t warn_fun);
|
||||
|
||||
/**
|
||||
* @brief Sets the verbosiness level
|
||||
*
|
||||
* When the verbosiness level is above zero, some functions might print
|
||||
* diagnostic information about what are they doing. The higher the level is,
|
||||
* the more detail is printed. Level zero is guaranteed to omit all such
|
||||
* output. The output is written using the same machinery as the warnings,
|
||||
* @see cpuid_set_warn_function()
|
||||
*
|
||||
* @param level the desired verbosiness level. Useful values 0..2 inclusive
|
||||
*/
|
||||
void cpuid_set_verbosiness_level(int level);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Obtains the CPU vendor from CPUID from the current CPU
|
||||
* @note The result is cached.
|
||||
* @returns VENDOR_UNKNOWN if failed, otherwise the CPU vendor type.
|
||||
* @see cpu_vendor_t
|
||||
*/
|
||||
cpu_vendor_t cpuid_get_vendor(void);
|
||||
|
||||
/**
|
||||
* @brief a structure that holds a list of processor names
|
||||
*/
|
||||
struct cpu_list_t {
|
||||
/** Number of entries in the list */
|
||||
int num_entries;
|
||||
/** Pointers to names. There will be num_entries of them */
|
||||
char **names;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets a list of all known CPU names from a specific vendor.
|
||||
*
|
||||
* This function compiles a list of all known CPU (code)names
|
||||
* (i.e. the possible values of cpu_id_t::cpu_codename) for the given vendor.
|
||||
*
|
||||
* There are about 100 entries for Intel and AMD, and a few for the other
|
||||
* vendors. The list is written out in approximate chronological introduction
|
||||
* order of the parts.
|
||||
*
|
||||
* @param vendor the vendor to be queried
|
||||
* @param list [out] the resulting list will be written here.
|
||||
* NOTE: As the memory is dynamically allocated, be sure to call
|
||||
* cpuid_free_cpu_list() after you're done with the data
|
||||
* @see cpu_list_t
|
||||
*/
|
||||
void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list);
|
||||
|
||||
/**
|
||||
* @brief Frees a CPU list
|
||||
*
|
||||
* This function deletes all the memory associated with a CPU list, as obtained
|
||||
* by cpuid_get_cpu_list()
|
||||
*
|
||||
* @param list - the list to be free()'d.
|
||||
*/
|
||||
void cpuid_free_cpu_list(struct cpu_list_t* list);
|
||||
|
||||
struct msr_driver_t;
|
||||
/**
|
||||
* @brief Starts/opens a driver, needed to read MSRs (Model Specific Registers)
|
||||
*
|
||||
* On systems that support it, this function will create a temporary
|
||||
* system driver, that has privileges to execute the RDMSR instruction.
|
||||
* After the driver is created, you can read MSRs by calling \ref cpu_rdmsr
|
||||
*
|
||||
* @returns a handle to the driver on success, and NULL on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
struct msr_driver_t* cpu_msr_driver_open(void);
|
||||
|
||||
/**
|
||||
* @brief Similar to \ref cpu_msr_driver_open, but accept one parameter
|
||||
*
|
||||
* This function works on certain operating systems (GNU/Linux, FreeBSD)
|
||||
*
|
||||
* @param core_num specify the core number for MSR.
|
||||
* The first core number is 0.
|
||||
* The last core number is \ref cpuid_get_total_cpus - 1.
|
||||
*
|
||||
* @returns a handle to the driver on success, and NULL on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num);
|
||||
|
||||
/**
|
||||
* @brief Reads a Model-Specific Register (MSR)
|
||||
*
|
||||
* If the CPU has MSRs (as indicated by the CPU_FEATURE_MSR flag), you can
|
||||
* read a MSR with the given index by calling this function.
|
||||
*
|
||||
* There are several prerequisites you must do before reading MSRs:
|
||||
* 1) You must ensure the CPU has RDMSR. Check the CPU_FEATURE_MSR flag
|
||||
* in cpu_id_t::flags
|
||||
* 2) You must ensure that the CPU implements the specific MSR you intend to
|
||||
* read.
|
||||
* 3) You must open a MSR-reader driver. RDMSR is a privileged instruction and
|
||||
* needs ring-0 access in order to work. This temporary driver is created
|
||||
* by calling \ref cpu_msr_driver_open
|
||||
*
|
||||
* @param handle - a handle to the MSR reader driver, as created by
|
||||
* cpu_msr_driver_open
|
||||
* @param msr_index - the numeric ID of the MSR you want to read
|
||||
* @param result - a pointer to a 64-bit integer, where the MSR value is stored
|
||||
*
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int cpu_rdmsr(struct msr_driver_t* handle, uint32_t msr_index, uint64_t* result);
|
||||
|
||||
|
||||
typedef enum {
|
||||
INFO_MPERF, /*!< Maximum performance frequency clock. This
|
||||
is a counter, which increments as a
|
||||
proportion of the actual processor speed. */
|
||||
INFO_APERF, /*!< Actual performance frequency clock. This
|
||||
accumulates the core clock counts when the
|
||||
core is active. */
|
||||
INFO_MIN_MULTIPLIER, /*!< Minimum CPU:FSB ratio for this CPU,
|
||||
multiplied by 100. */
|
||||
INFO_CUR_MULTIPLIER, /*!< Current CPU:FSB ratio, multiplied by 100.
|
||||
e.g., a CPU:FSB value of 18.5 reads as
|
||||
"1850". */
|
||||
INFO_MAX_MULTIPLIER, /*!< Maximum CPU:FSB ratio for this CPU,
|
||||
multiplied by 100. */
|
||||
INFO_TEMPERATURE, /*!< The current core temperature in Celsius. */
|
||||
INFO_THROTTLING, /*!< 1 if the current logical processor is
|
||||
throttling. 0 if it is running normally. */
|
||||
INFO_VOLTAGE, /*!< The current core voltage in Volt,
|
||||
multiplied by 100. */
|
||||
INFO_BCLK, /*!< See \ref INFO_BUS_CLOCK. */
|
||||
INFO_BUS_CLOCK, /*!< The main bus clock in MHz,
|
||||
e.g., FSB/QPI/DMI/HT base clock,
|
||||
multiplied by 100. */
|
||||
} cpu_msrinfo_request_t;
|
||||
|
||||
/**
|
||||
* @brief Similar to \ref cpu_rdmsr, but extract a range of bits
|
||||
*
|
||||
* @param handle - a handle to the MSR reader driver, as created by
|
||||
* cpu_msr_driver_open
|
||||
* @param msr_index - the numeric ID of the MSR you want to read
|
||||
* @param highbit - the high bit in range, must be inferior to 64
|
||||
* @param lowbit - the low bit in range, must be equal or superior to 0
|
||||
* @param result - a pointer to a 64-bit integer, where the MSR value is stored
|
||||
*
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
|
||||
uint8_t lowbit, uint64_t* result);
|
||||
|
||||
/**
|
||||
* @brief Reads extended CPU information from Model-Specific Registers.
|
||||
* @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open
|
||||
* @param which - which info field should be returned. A list of
|
||||
* available information entities is listed in the
|
||||
* cpu_msrinfo_request_t enum.
|
||||
* @retval - if the requested information is available for the current
|
||||
* processor model, the respective value is returned.
|
||||
* if no information is available, or the CPU doesn't support
|
||||
* the query, the special value CPU_INVALID_VALUE is returned
|
||||
* @note This function is not MT-safe. If you intend to call it from multiple
|
||||
* threads, guard it through a mutex or a similar primitive.
|
||||
*/
|
||||
int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which);
|
||||
#define CPU_INVALID_VALUE 0x3fffffff
|
||||
|
||||
/**
|
||||
* @brief Writes the raw MSR data to a text file
|
||||
* @param data - a pointer to msr_driver_t structure
|
||||
* @param filename - the path of the file, where the serialized data should be
|
||||
* written. If empty, stdout will be used.
|
||||
* @note This is intended primarily for debugging. On some processor, which is
|
||||
* not currently supported or not completely recognized by cpu_identify,
|
||||
* one can still successfully get the raw data and write it to a file.
|
||||
* libcpuid developers can later import this file and debug the detection
|
||||
* code as if running on the actual hardware.
|
||||
* The file is simple text format of "something=value" pairs. Version info
|
||||
* is also written, but the format is not intended to be neither backward-
|
||||
* nor forward compatible.
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Closes an open MSR driver
|
||||
*
|
||||
* This function unloads the MSR driver opened by cpu_msr_driver_open and
|
||||
* frees any resources associated with it.
|
||||
*
|
||||
* @param handle - a handle to the MSR reader driver, as created by
|
||||
* cpu_msr_driver_open
|
||||
*
|
||||
* @returns zero if successful, and some negative number on error.
|
||||
* The error message can be obtained by calling \ref cpuid_error.
|
||||
* @see cpu_error_t
|
||||
*/
|
||||
int cpu_msr_driver_close(struct msr_driver_t* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; /* extern "C" */
|
||||
#endif
|
||||
|
|
125
src/3rdparty/libcpuid/libcpuid_util.c
vendored
125
src/3rdparty/libcpuid/libcpuid_util.c
vendored
|
@ -32,8 +32,6 @@
|
|||
#include "libcpuid.h"
|
||||
#include "libcpuid_util.h"
|
||||
|
||||
int _current_verboselevel;
|
||||
|
||||
void match_features(const struct feature_map_t* matchtable, int count, uint32_t reg, struct cpu_id_t* data)
|
||||
{
|
||||
int i;
|
||||
|
@ -42,118 +40,6 @@ void match_features(const struct feature_map_t* matchtable, int count, uint32_t
|
|||
data->flags[matchtable[i].feature] = 1;
|
||||
}
|
||||
|
||||
static void default_warn(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s", msg);
|
||||
}
|
||||
|
||||
libcpuid_warn_fn_t _warn_fun = default_warn;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define vsnprintf _vsnprintf
|
||||
#endif
|
||||
void warnf(const char* format, ...)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list va;
|
||||
if (!_warn_fun) return;
|
||||
va_start(va, format);
|
||||
vsnprintf(buff, sizeof(buff), format, va);
|
||||
va_end(va);
|
||||
_warn_fun(buff);
|
||||
}
|
||||
|
||||
void debugf(int verboselevel, const char* format, ...)
|
||||
{
|
||||
char buff[1024];
|
||||
va_list va;
|
||||
if (verboselevel > _current_verboselevel) return;
|
||||
va_start(va, format);
|
||||
vsnprintf(buff, sizeof(buff), format, va);
|
||||
va_end(va);
|
||||
_warn_fun(buff);
|
||||
}
|
||||
|
||||
static int popcount64(uint64_t mask)
|
||||
{
|
||||
int num_set_bits = 0;
|
||||
|
||||
while (mask) {
|
||||
mask &= mask - 1;
|
||||
num_set_bits++;
|
||||
}
|
||||
|
||||
return num_set_bits;
|
||||
}
|
||||
|
||||
static int score(const struct match_entry_t* entry, const struct cpu_id_t* data,
|
||||
int brand_code, uint64_t bits, int model_code)
|
||||
{
|
||||
int res = 0;
|
||||
if (entry->family == data->family ) res += 2;
|
||||
if (entry->model == data->model ) res += 2;
|
||||
if (entry->stepping == data->stepping ) res += 2;
|
||||
if (entry->ext_family == data->ext_family) res += 2;
|
||||
if (entry->ext_model == data->ext_model ) res += 2;
|
||||
if (entry->ncores == data->num_cores ) res += 2;
|
||||
if (entry->l2cache == data->l2_cache ) res += 1;
|
||||
if (entry->l3cache == data->l3_cache ) res += 1;
|
||||
if (entry->brand_code == brand_code ) res += 2;
|
||||
if (entry->model_code == model_code ) res += 2;
|
||||
|
||||
res += popcount64(entry->model_bits & bits) * 2;
|
||||
return res;
|
||||
}
|
||||
|
||||
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
|
||||
struct cpu_id_t* data, int brand_code, uint64_t bits,
|
||||
int model_code)
|
||||
{
|
||||
int bestscore = -1;
|
||||
int bestindex = 0;
|
||||
int i, t;
|
||||
|
||||
debugf(3, "Matching cpu f:%d, m:%d, s:%d, xf:%d, xm:%d, ncore:%d, l2:%d, bcode:%d, bits:%llu, code:%d\n",
|
||||
data->family, data->model, data->stepping, data->ext_family,
|
||||
data->ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
t = score(&matchtable[i], data, brand_code, bits, model_code);
|
||||
debugf(3, "Entry %d, `%s', score %d\n", i, matchtable[i].name, t);
|
||||
if (t > bestscore) {
|
||||
debugf(2, "Entry `%s' selected - best score so far (%d)\n", matchtable[i].name, t);
|
||||
bestscore = t;
|
||||
bestindex = i;
|
||||
}
|
||||
}
|
||||
strcpy(data->cpu_codename, matchtable[bestindex].name);
|
||||
return bestscore;
|
||||
}
|
||||
|
||||
void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
|
||||
struct cpu_list_t* list)
|
||||
{
|
||||
int i, j, n, good;
|
||||
n = 0;
|
||||
list->names = (char**) malloc(sizeof(char*) * count);
|
||||
for (i = 0; i < count; i++) {
|
||||
if (strstr(matchtable[i].name, "Unknown")) continue;
|
||||
good = 1;
|
||||
for (j = n - 1; j >= 0; j--)
|
||||
if (!strcmp(list->names[j], matchtable[i].name)) {
|
||||
good = 0;
|
||||
break;
|
||||
}
|
||||
if (!good) continue;
|
||||
#if defined(_MSC_VER)
|
||||
list->names[n++] = _strdup(matchtable[i].name);
|
||||
#else
|
||||
list->names[n++] = strdup(matchtable[i].name);
|
||||
#endif
|
||||
}
|
||||
list->num_entries = n;
|
||||
}
|
||||
|
||||
static int xmatch_entry(char c, const char* p)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -205,14 +91,3 @@ int match_all(uint64_t bits, uint64_t mask)
|
|||
{
|
||||
return (bits & mask) == mask;
|
||||
}
|
||||
|
||||
void debug_print_lbits(int debuglevel, uint64_t mask)
|
||||
{
|
||||
int i, first = 0;
|
||||
for (i = 0; i < 64; i++) if (mask & (((uint64_t) 1) << i)) {
|
||||
if (first) first = 0;
|
||||
else debugf(2, " + ");
|
||||
debugf(2, "LBIT(%d)", i);
|
||||
}
|
||||
debugf(2, "\n");
|
||||
}
|
||||
|
|
20
src/3rdparty/libcpuid/libcpuid_util.h
vendored
20
src/3rdparty/libcpuid/libcpuid_util.h
vendored
|
@ -48,20 +48,6 @@ struct match_entry_t {
|
|||
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
|
||||
struct cpu_id_t* data, int brand_code, uint64_t bits,
|
||||
int model_code);
|
||||
|
||||
void warnf(const char* format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
void debugf(int verboselevel, const char* format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
|
||||
struct cpu_list_t* list);
|
||||
|
||||
/*
|
||||
* Seek for a pattern in `haystack'.
|
||||
* Pattern may be an fixed string, or contain the special metacharacters
|
||||
|
@ -84,15 +70,9 @@ struct cpu_id_t* get_cached_cpuid(void);
|
|||
/* returns true if all bits of mask are present in `bits'. */
|
||||
int match_all(uint64_t bits, uint64_t mask);
|
||||
|
||||
/* print what bits a mask consists of */
|
||||
void debug_print_lbits(int debuglevel, uint64_t mask);
|
||||
|
||||
/*
|
||||
* Sets the current errno
|
||||
*/
|
||||
int set_error(cpu_error_t err);
|
||||
|
||||
extern libcpuid_warn_fn_t _warn_fun;
|
||||
extern int _current_verboselevel;
|
||||
|
||||
#endif /* __LIBCPUID_UTIL_H__ */
|
||||
|
|
361
src/3rdparty/libcpuid/recog_amd.c
vendored
361
src/3rdparty/libcpuid/recog_amd.c
vendored
|
@ -51,237 +51,6 @@ enum _amd_model_codes_t {
|
|||
_1600,
|
||||
};
|
||||
|
||||
|
||||
const struct match_entry_t cpudb_amd[] = {
|
||||
{ -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD CPU" },
|
||||
|
||||
/* 486 and the likes */
|
||||
{ 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 486" },
|
||||
{ 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2" },
|
||||
{ 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2WB" },
|
||||
{ 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4" },
|
||||
{ 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4WB" },
|
||||
|
||||
/* Pentia clones */
|
||||
{ 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 586" },
|
||||
{ 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
|
||||
{ 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
|
||||
{ 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
|
||||
{ 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
|
||||
|
||||
/* The K6 */
|
||||
{ 5, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
|
||||
{ 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
|
||||
|
||||
{ 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2" },
|
||||
{ 5, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-III" },
|
||||
{ 5, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
|
||||
{ 5, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
|
||||
{ 5, 12, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
|
||||
{ 5, 13, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2+" },
|
||||
|
||||
/* Athlon et al. */
|
||||
{ 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
|
||||
{ 6, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
|
||||
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Duron (Spitfire)" },
|
||||
{ 6, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (ThunderBird)" },
|
||||
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon (Palomino)" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Palomino)" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Palomino)" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP" },
|
||||
|
||||
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon XP" },
|
||||
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Morgan)" },
|
||||
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon XP (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Applebred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Thoroughbred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_ , 0, "Mobile Athlon (T-Bred)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_|_LV_, 0, "Mobile Athlon (T-Bred)" },
|
||||
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP (Barton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, 512, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Barton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron (Barton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thorton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, 256, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Thorton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Barton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_ , 0, "Mobile Athlon (Barton)" },
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_|_LV_, 0, "Mobile Athlon (Barton)" },
|
||||
|
||||
/* K8 Architecture */
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown K8" },
|
||||
{ 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Unknown K9" },
|
||||
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown A64" },
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
|
||||
{ 15, -1, -1, 15, -1, 2, -1, -1, NC, OPTERON_|_X2 , 0, "Opteron (Dual Core)" },
|
||||
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
|
||||
{ 15, 3, -1, 15, -1, 2, -1, -1, NC, OPTERON_|_X2 , 0, "Opteron (Dual Core)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (512K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (1024K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_|_FX , 0, "Athlon FX" },
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_|_64_|_FX , 0, "Athlon 64 FX" },
|
||||
{ 15, 3, -1, 15, 35, 2, -1, -1, NC, ATHLON_|_64_|_FX , 0, "Athlon 64 FX X2 (Toledo)" },
|
||||
{ 15, -1, -1, 15, -1, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (512K)" },
|
||||
{ 15, -1, -1, 15, -1, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (1024K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (512K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 1024, -1, NC, TURION_|_64_ , 0, "Turion 64 (1024K)" },
|
||||
{ 15, -1, -1, 15, -1, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion 64 X2 (512K)" },
|
||||
{ 15, -1, -1, 15, -1, 2, 1024, -1, NC, TURION_|_X2 , 0, "Turion 64 X2 (1024K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 128, -1, NC, SEMPRON_ , 0, "A64 Sempron (128K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 256, -1, NC, SEMPRON_ , 0, "A64 Sempron (256K)" },
|
||||
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, SEMPRON_ , 0, "A64 Sempron (512K)" },
|
||||
{ 15, -1, -1, 15, 0x4f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/512K)" },
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/512K)" },
|
||||
{ 15, -1, -1, 15, 0x2f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Venice/512K)" },
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Venice/512K)" },
|
||||
{ 15, -1, -1, 15, 0x1f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Winchester/512K)" },
|
||||
{ 15, -1, -1, 15, 0x0c, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Newcastle/512K)" },
|
||||
{ 15, -1, -1, 15, 0x27, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/512K)" },
|
||||
{ 15, -1, -1, 15, 0x37, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/512K)" },
|
||||
{ 15, -1, -1, 15, 0x04, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (ClawHammer/512K)" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x27, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x04, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (ClawHammer/1024K)" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x4b, 2, 256, -1, NC, SEMPRON_ , 0, "Athlon 64 X2 (Windsor/256K)" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x23, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Toledo/512K)" },
|
||||
{ 15, -1, -1, 15, 0x4b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
|
||||
{ 15, -1, -1, 15, 0x43, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
|
||||
{ 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Brisbane/512K)" },
|
||||
{ 15, -1, -1, 15, 0x2b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Manchester/512K)"},
|
||||
|
||||
{ 15, -1, -1, 15, 0x23, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Toledo/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x43, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/1024K)" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x08, 1, 128, -1, NC, MOBILE_|SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/128K)"},
|
||||
{ 15, -1, -1, 15, 0x08, 1, 256, -1, NC, MOBILE_|SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/256K)"},
|
||||
{ 15, -1, -1, 15, 0x0c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Paris)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/128K)"},
|
||||
{ 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/256K)"},
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Albany/128K)"},
|
||||
{ 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Albany/256K)"},
|
||||
{ 15, -1, -1, 15, 0x2f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
|
||||
{ 15, -1, -1, 15, 0x2f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
|
||||
{ 15, -1, -1, 15, 0x4f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
|
||||
{ 15, -1, -1, 15, 0x4f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
|
||||
{ 15, -1, -1, 15, 0x5f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
|
||||
{ 15, -1, -1, 15, 0x6b, 2, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/256K)"},
|
||||
{ 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/512K)"},
|
||||
{ 15, -1, -1, 15, 0x7f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/256K)" },
|
||||
{ 15, -1, -1, 15, 0x7f, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/512K)" },
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Keene/256K)"},
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Keene/512K)"},
|
||||
{ 15, -1, -1, 15, -1, 2, -1, -1, NC, SEMPRON_ , 0, "Sempron Dual Core" },
|
||||
|
||||
{ 15, -1, -1, 15, 0x24, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (Lancaster/512K)" },
|
||||
{ 15, -1, -1, 15, 0x24, 1, 1024, -1, NC, TURION_|_64_ , 0, "Turion 64 (Lancaster/1024K)" },
|
||||
{ 15, -1, -1, 15, 0x48, 2, 256, -1, NC, TURION_|_X2 , 0, "Turion X2 (Taylor)" },
|
||||
{ 15, -1, -1, 15, 0x48, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Trinidad)" },
|
||||
{ 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (Richmond)" },
|
||||
{ 15, -1, -1, 15, 0x68, 2, 256, -1, NC, TURION_|_X2 , 0, "Turion X2 (Tyler/256K)" },
|
||||
{ 15, -1, -1, 15, 0x68, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Tyler/512K)" },
|
||||
{ 15, -1, -1, 17, 3, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Griffin/512K)" },
|
||||
{ 15, -1, -1, 17, 3, 2, 1024, -1, NC, TURION_|_X2 , 0, "Turion X2 (Griffin/1024K)" },
|
||||
|
||||
/* K10 Architecture (2007) */
|
||||
{ 15, -1, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Unknown AMD Phenom" },
|
||||
{ 15, 2, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Phenom" },
|
||||
{ 15, 2, -1, 16, -1, 3, -1, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman)" },
|
||||
{ 15, 2, -1, 16, -1, 4, -1, -1, PHENOM, 0 , 0, "Phenom X4 (Agena)" },
|
||||
{ 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/256K)" },
|
||||
{ 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/512K)" },
|
||||
{ 15, 2, -1, 16, -1, 4, 128, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/128K)" },
|
||||
{ 15, 2, -1, 16, -1, 4, 256, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/256K)" },
|
||||
{ 15, 2, -1, 16, -1, 4, 512, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/512K)" },
|
||||
{ 15, 2, -1, 16, -1, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon X2 (Kuma)" },
|
||||
/* Phenom II derivates: */
|
||||
{ 15, 4, -1, 16, -1, 4, -1, -1, NC, 0 , 0, "Phenom (Deneb-based)" },
|
||||
{ 15, 4, -1, 16, -1, 1, 1024, -1, NC, SEMPRON_ , 0, "Sempron (Sargas)" },
|
||||
{ 15, 4, -1, 16, -1, 2, 512, -1, PHENOM2, 0 , 0, "Phenom II X2 (Callisto)" },
|
||||
{ 15, 4, -1, 16, -1, 3, 512, -1, PHENOM2, 0 , 0, "Phenom II X3 (Heka)" },
|
||||
{ 15, 4, -1, 16, -1, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4" },
|
||||
{ 15, 4, -1, 16, 4, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
|
||||
{ 15, 5, -1, 16, 5, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
|
||||
{ 15, 4, -1, 16, 10, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Zosma)" },
|
||||
{ 15, 4, -1, 16, 10, 6, 512, -1, PHENOM2, 0 , 0, "Phenom II X6 (Thuban)" },
|
||||
/* Athlon II derivates: */
|
||||
{ 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_|_X2 , 0, "Athlon II (Champlain)" },
|
||||
{ 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon II X2 (Regor)" },
|
||||
{ 15, 6, -1, 16, 6, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon II X2 (Regor)" },
|
||||
{ 15, 5, -1, 16, 5, 3, 512, -1, NC, ATHLON_|_64_|_X3 , 0, "Athlon II X3 (Rana)" },
|
||||
{ 15, 5, -1, 16, 5, 4, 512, -1, NC, ATHLON_|_64_|_X4 , 0, "Athlon II X4 (Propus)" },
|
||||
/* Llano APUs (2011): */
|
||||
{ 15, 1, -1, 18, 1, 2, -1, -1, FUSION_EA, 0 , 0, "Llano X2" },
|
||||
{ 15, 1, -1, 18, 1, 3, -1, -1, FUSION_EA, 0 , 0, "Llano X3" },
|
||||
{ 15, 1, -1, 18, 1, 4, -1, -1, FUSION_EA, 0 , 0, "Llano X4" },
|
||||
|
||||
/* Family 14h: Bobcat Architecture (2011) */
|
||||
{ 15, 2, -1, 20, -1, 1, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario" },
|
||||
{ 15, 2, -1, 20, -1, 2, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario (Dual-core)" },
|
||||
{ 15, 1, -1, 20, -1, 1, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate" },
|
||||
{ 15, 1, -1, 20, -1, 2, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate (Dual-core)" },
|
||||
{ 15, 2, -1, 20, -1, 2, -1, -1, FUSION_Z, 0 , 0, "Brazos Desna (Dual-core)" },
|
||||
|
||||
/* Family 15h: Bulldozer Architecture (2011) */
|
||||
{ 15, -1, -1, 21, 0, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
|
||||
{ 15, -1, -1, 21, 1, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
|
||||
{ 15, -1, -1, 21, 1, 6, -1, -1, NC, 0 , 0, "Bulldozer X3" },
|
||||
{ 15, -1, -1, 21, 1, 8, -1, -1, NC, 0 , 0, "Bulldozer X4" },
|
||||
/* 2nd-gen, Piledriver core (2012): */
|
||||
{ 15, -1, -1, 21, 2, 4, -1, -1, NC, 0 , 0, "Vishera X2" },
|
||||
{ 15, -1, -1, 21, 2, 6, -1, -1, NC, 0 , 0, "Vishera X3" },
|
||||
{ 15, -1, -1, 21, 2, 8, -1, -1, NC, 0 , 0, "Vishera X4" },
|
||||
{ 15, 0, -1, 21, 16, 2, -1, -1, FUSION_A, 0 , 0, "Trinity X2" },
|
||||
{ 15, 0, -1, 21, 16, 4, -1, -1, FUSION_A, 0 , 0, "Trinity X4" },
|
||||
{ 15, 3, -1, 21, 19, 2, -1, -1, FUSION_A, 0 , 0, "Richland X2" },
|
||||
{ 15, 3, -1, 21, 19, 4, -1, -1, FUSION_A, 0 , 0, "Richland X4" },
|
||||
/* 3rd-gen, Steamroller core (2014): */
|
||||
{ 15, 0, -1, 21, 48, 2, -1, -1, FUSION_A, 0 , 0, "Kaveri X2" },
|
||||
{ 15, 0, -1, 21, 48, 4, -1, -1, FUSION_A, 0 , 0, "Kaveri X4" },
|
||||
{ 15, 8, -1, 21, 56, 4, -1, -1, FUSION_A, 0 , 0, "Godavari X4" },
|
||||
/* 4th-gen, Excavator core (2015): */
|
||||
{ 15, 1, -1, 21, 96, 2, -1, -1, FUSION_A, 0 , 0, "Carrizo X2" },
|
||||
{ 15, 1, -1, 21, 96, 4, -1, -1, FUSION_A, 0 , 0, "Carrizo X4" },
|
||||
{ 15, 5, -1, 21, 101, 2, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X2" },
|
||||
{ 15, 5, -1, 21, 101, 4, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X4" },
|
||||
{ 15, 0, -1, 21, 112, 2, -1, -1, FUSION_A, 0 , 0, "Stoney Ridge X2" },
|
||||
{ 15, 0, -1, 21, 112, 2, -1, -1, FUSION_E, 0 , 0, "Stoney Ridge X2" },
|
||||
|
||||
/* Family 16h: Jaguar Architecture (2013) */
|
||||
{ 15, 0, -1, 22, 0, 2, -1, -1, FUSION_A, 0 , 0, "Kabini X2" },
|
||||
{ 15, 0, -1, 22, 0, 4, -1, -1, FUSION_A, 0 , 0, "Kabini X4" },
|
||||
/* 2nd-gen, Puma core (2013): */
|
||||
{ 15, 0, -1, 22, 48, 2, -1, -1, FUSION_E, 0 , 0, "Mullins X2" },
|
||||
{ 15, 0, -1, 22, 48, 4, -1, -1, FUSION_A, 0 , 0, "Mullins X4" },
|
||||
|
||||
/* Family 17h: Zen Architecture (2017) */
|
||||
{ 15, -1, -1, 23, 1, 8, -1, -1, NC, 0 , 0, "Ryzen 7" },
|
||||
{ 15, -1, -1, 23, 1, 6, -1, -1, NC, 0 , _1600, "Ryzen 5" },
|
||||
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1500, "Ryzen 5" },
|
||||
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1400, "Ryzen 5" },
|
||||
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Ryzen 3" },
|
||||
//{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Raven Ridge" }, //TBA
|
||||
|
||||
/* Newer Opterons: */
|
||||
{ 15, 9, -1, 22, 9, 8, -1, -1, NC, OPTERON_ , 0, "Magny-Cours Opteron" },
|
||||
};
|
||||
|
||||
|
||||
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||
{
|
||||
const struct feature_map_t matchtable_edx81[] = {
|
||||
|
@ -391,140 +160,10 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
|
|||
}
|
||||
}
|
||||
|
||||
static int amd_has_turion_modelname(const char *bs)
|
||||
{
|
||||
/* We search for something like TL-60. Ahh, I miss regexes...*/
|
||||
int i, l, k;
|
||||
char code[3] = {0};
|
||||
const char* codes[] = { "ML", "MT", "MK", "TK", "TL", "RM", "ZM", "" };
|
||||
l = (int) strlen(bs);
|
||||
for (i = 3; i < l - 2; i++) {
|
||||
if (bs[i] == '-' &&
|
||||
isupper(bs[i-1]) && isupper(bs[i-2]) && !isupper(bs[i-3]) &&
|
||||
isdigit(bs[i+1]) && isdigit(bs[i+2]) && !isdigit(bs[i+3]))
|
||||
{
|
||||
code[0] = bs[i-2];
|
||||
code[1] = bs[i-1];
|
||||
for (k = 0; codes[k][0]; k++)
|
||||
if (!strcmp(codes[k], code)) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs)
|
||||
{
|
||||
amd_code_t code = NC;
|
||||
uint64_t bits = 0;
|
||||
struct amd_code_and_bits_t result;
|
||||
|
||||
if (strstr(bs, "Dual Core") ||
|
||||
strstr(bs, "Dual-Core") ||
|
||||
strstr(bs, " X2 "))
|
||||
bits |= _X2;
|
||||
if (strstr(bs, " X4 ")) bits |= _X4;
|
||||
if (strstr(bs, " X3 ")) bits |= _X3;
|
||||
if (strstr(bs, "Opteron")) bits |= OPTERON_;
|
||||
if (strstr(bs, "Phenom")) {
|
||||
code = (strstr(bs, "II")) ? PHENOM2 : PHENOM;
|
||||
}
|
||||
if (amd_has_turion_modelname(bs)) {
|
||||
bits |= TURION_;
|
||||
}
|
||||
if (strstr(bs, "Athlon(tm)")) bits |= ATHLON_;
|
||||
if (strstr(bs, "Sempron(tm)")) bits |= SEMPRON_;
|
||||
if (strstr(bs, "Duron")) bits |= DURON_;
|
||||
if (strstr(bs, " 64 ")) bits |= _64_;
|
||||
if (strstr(bs, " FX")) bits |= _FX;
|
||||
if (strstr(bs, " MP")) bits |= _MP_;
|
||||
if (strstr(bs, "Athlon(tm) 64") || strstr(bs, "Athlon(tm) II X") || match_pattern(bs, "Athlon(tm) X#")) {
|
||||
bits |= ATHLON_ | _64_;
|
||||
}
|
||||
if (strstr(bs, "Turion")) bits |= TURION_;
|
||||
|
||||
if (strstr(bs, "mobile") || strstr(bs, "Mobile")) {
|
||||
bits |= MOBILE_;
|
||||
}
|
||||
|
||||
if (strstr(bs, "XP")) bits |= _XP_;
|
||||
if (strstr(bs, "XP-M")) bits |= _M_;
|
||||
if (strstr(bs, "(LV)")) bits |= _LV_;
|
||||
if (strstr(bs, " APU ")) bits |= _APU_;
|
||||
|
||||
if (match_pattern(bs, "C-##")) code = FUSION_C;
|
||||
if (match_pattern(bs, "E-###")) code = FUSION_E;
|
||||
if (match_pattern(bs, "Z-##")) code = FUSION_Z;
|
||||
if (match_pattern(bs, "[EA]#-####")) code = FUSION_EA;
|
||||
|
||||
result.code = code;
|
||||
result.bits = bits;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int decode_amd_ryzen_model_code(const char* bs)
|
||||
{
|
||||
const struct {
|
||||
int model_code;
|
||||
const char* match_str;
|
||||
} patterns[] = {
|
||||
{ _1600, "1600" },
|
||||
{ _1500, "1500" },
|
||||
{ _1400, "1400" },
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < COUNT_OF(patterns); i++)
|
||||
if (strstr(bs, patterns[i].match_str))
|
||||
return patterns[i].model_code;
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
||||
{
|
||||
struct amd_code_and_bits_t code_and_bits = decode_amd_codename_part1(data->brand_str);
|
||||
int i = 0;
|
||||
char* code_str = NULL;
|
||||
int model_code;
|
||||
|
||||
for (i = 0; i < COUNT_OF(amd_code_str); i++) {
|
||||
if (code_and_bits.code == amd_code_str[i].code) {
|
||||
code_str = amd_code_str[i].str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (/*code == ATHLON_64_X2*/ match_all(code_and_bits.bits, ATHLON_|_64_|_X2) && data->l2_cache < 512) {
|
||||
code_and_bits.bits &= ~(ATHLON_ | _64_);
|
||||
code_and_bits.bits |= SEMPRON_;
|
||||
}
|
||||
if (code_str)
|
||||
debugf(2, "Detected AMD brand code: %d (%s)\n", code_and_bits.code, code_str);
|
||||
else
|
||||
debugf(2, "Detected AMD brand code: %d\n", code_and_bits.code);
|
||||
|
||||
if (code_and_bits.bits) {
|
||||
debugf(2, "Detected AMD bits: ");
|
||||
debug_print_lbits(2, code_and_bits.bits);
|
||||
}
|
||||
// is it Ryzen? if so, we need to detect discern between the four-core 1400/1500 (Ryzen 5) and the four-core Ryzen 3:
|
||||
model_code = (data->ext_family == 23) ? decode_amd_ryzen_model_code(data->brand_str) : 0;
|
||||
|
||||
internal->code.amd = code_and_bits.code;
|
||||
internal->bits = code_and_bits.bits;
|
||||
internal->score = match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code_and_bits.code,
|
||||
code_and_bits.bits, model_code);
|
||||
}
|
||||
|
||||
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
||||
{
|
||||
load_amd_features(raw, data);
|
||||
decode_amd_cache_info(raw, data);
|
||||
decode_amd_number_of_cores(raw, data);
|
||||
decode_amd_codename(raw, data, internal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cpuid_get_list_amd(struct cpu_list_t* list)
|
||||
{
|
||||
generic_get_cpu_list(cpudb_amd, COUNT_OF(cpudb_amd), list);
|
||||
}
|
||||
|
|
1
src/3rdparty/libcpuid/recog_amd.h
vendored
1
src/3rdparty/libcpuid/recog_amd.h
vendored
|
@ -27,6 +27,5 @@
|
|||
#define __RECOG_AMD_H__
|
||||
|
||||
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
|
||||
void cpuid_get_list_amd(struct cpu_list_t* list);
|
||||
|
||||
#endif /* __RECOG_AMD_H__ */
|
||||
|
|
376
src/3rdparty/libcpuid/recog_intel.c
vendored
376
src/3rdparty/libcpuid/recog_intel.c
vendored
|
@ -59,291 +59,6 @@ enum _intel_model_t {
|
|||
};
|
||||
typedef enum _intel_model_t intel_model_t;
|
||||
|
||||
const struct match_entry_t cpudb_intel[] = {
|
||||
{ -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" },
|
||||
|
||||
/* i486 */
|
||||
{ 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown i486" },
|
||||
{ 4, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-25/33" },
|
||||
{ 4, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-50" },
|
||||
{ 4, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX" },
|
||||
{ 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2" },
|
||||
{ 4, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SL" },
|
||||
{ 4, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX2" },
|
||||
{ 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2 WriteBack" },
|
||||
{ 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4" },
|
||||
{ 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4 WriteBack" },
|
||||
|
||||
/* All Pentia:
|
||||
Pentium 1 */
|
||||
{ 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium" },
|
||||
{ 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium A-Step" },
|
||||
{ 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.8u)" },
|
||||
{ 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
|
||||
{ 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium OverDrive" },
|
||||
{ 5, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
|
||||
{ 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
|
||||
{ 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium MMX (0.25u)" },
|
||||
|
||||
/* Pentium 2 / 3 / M / Conroe / whatsnext - all P6 based. */
|
||||
{ 6, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown P6" },
|
||||
{ 6, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
|
||||
{ 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
|
||||
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Klamath)" },
|
||||
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Deschutes)" },
|
||||
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile Pentium II (Tonga)"},
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC,0 , 0, "Pentium II (Dixon)" },
|
||||
|
||||
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Klamath)" },
|
||||
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Drake)" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Dixon)" },
|
||||
|
||||
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Covington)" },
|
||||
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Mendocino)" },
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Katmai)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
|
||||
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Tualatin)" },
|
||||
|
||||
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tanner)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
|
||||
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tualatin)" },
|
||||
|
||||
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Katmai)" },
|
||||
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
|
||||
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
|
||||
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Tualatin)" },
|
||||
|
||||
/* Netburst based (Pentium 4 and later)
|
||||
classic P4s */
|
||||
{ 15, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium 4" },
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "Unknown P-4 Celeron" },
|
||||
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Unknown Xeon" },
|
||||
|
||||
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
|
||||
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
|
||||
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Northwood)" },
|
||||
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
|
||||
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Cedar Mill)" },
|
||||
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Willamette)" },
|
||||
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Willamette)" },
|
||||
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Northwood)" },
|
||||
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Prescott)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Prescott)" },
|
||||
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Cedar Mill)" },
|
||||
|
||||
/* server CPUs */
|
||||
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
|
||||
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
|
||||
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" },
|
||||
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Gallatin)" },
|
||||
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Cranford)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" },
|
||||
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" },
|
||||
|
||||
/* Pentium Ds */
|
||||
{ 15, 4, 4, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (SmithField)" },
|
||||
{ 15, 4, 7, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
|
||||
{ 15, 6, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (Presler)" },
|
||||
|
||||
/* Celeron and Celeron Ds */
|
||||
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Willamette)" },
|
||||
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Northwood)" },
|
||||
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
|
||||
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
|
||||
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Cedar Mill)" },
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* Intel Core microarchitecture - P6-based */
|
||||
|
||||
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium M" },
|
||||
{ 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Unknown Pentium M" },
|
||||
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Banias)" },
|
||||
{ 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Banias)" },
|
||||
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
|
||||
{ 6, 13, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Dothan)" },
|
||||
{ 6, 13, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Dothan)" },
|
||||
{ 6, 13, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
|
||||
|
||||
{ 6, 12, -1, -1, -1, -1, -1, -1, NC, ATOM_ , 0, "Unknown Atom" },
|
||||
{ 6, 12, -1, -1, -1, -1, -1, -1, DIAMONDVILLE,ATOM_, 0, "Atom (Diamondville)" },
|
||||
{ 6, 12, -1, -1, -1, -1, -1, -1, SILVERTHORNE,ATOM_, 0, "Atom (Silverthorne)" },
|
||||
{ 6, 12, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
|
||||
{ 6, 6, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
|
||||
{ 6, 12, -1, -1, -1, -1, -1, -1, PINEVIEW, ATOM_ , 0, "Atom (Pineview)" },
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
{ 6, 14, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Yonah" },
|
||||
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
|
||||
{ 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO, 0 , 0, "Yonah (Core Duo)" },
|
||||
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, MOBILE_, 0, "Yonah (Core Solo)" },
|
||||
{ 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO , MOBILE_, 0, "Yonah (Core Duo)" },
|
||||
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
|
||||
|
||||
{ 6, 15, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Core 2" },
|
||||
{ 6, 15, -1, -1, -1, 2, 4096, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo)" },
|
||||
{ 6, 15, -1, -1, -1, 2, 1024, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 1024K" },
|
||||
{ 6, 15, -1, -1, -1, 2, 512, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 512K" },
|
||||
{ 6, 15, -1, -1, -1, 4, -1, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
|
||||
{ 6, 15, -1, -1, -1, 4, 4096, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
|
||||
{ 6, 15, -1, -1, -1, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
|
||||
{ 6, 15, -1, -1, -1, 2, 2048, -1, CORE_DUO, 0 , 0, "Allendale (Core 2 Duo)" },
|
||||
{ 6, 15, -1, -1, -1, 2, -1, -1, MOBILE_CORE_DUO, 0, 0, "Merom (Core 2 Duo)" },
|
||||
{ 6, 15, -1, -1, -1, 2, 2048, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 2048K" },
|
||||
{ 6, 15, -1, -1, -1, 2, 4096, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 4096K" },
|
||||
|
||||
{ 6, 15, -1, -1, 15, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
|
||||
{ 6, 6, -1, -1, 22, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
|
||||
{ 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
|
||||
{ 6, 6, -1, -1, 22, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
|
||||
|
||||
|
||||
{ 6, 6, -1, -1, 22, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
|
||||
{ 6, 7, -1, -1, 23, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
|
||||
{ 6, 6, -1, -1, 22, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
|
||||
{ 6, 7, -1, -1, 23, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
|
||||
|
||||
{ 6, 7, -1, -1, 23, 1, -1, -1, CORE_SOLO , 0, 0, "Unknown Core 45nm" },
|
||||
{ 6, 7, -1, -1, 23, 1, -1, -1, CORE_DUO , 0, 0, "Unknown Core 45nm" },
|
||||
{ 6, 7, -1, -1, 23, 2, 1024, -1, WOLFDALE , 0, 0, "Celeron Wolfdale 1M" },
|
||||
{ 6, 7, -1, -1, 23, 2, 2048, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 2M" },
|
||||
{ 6, 7, -1, -1, 23, 2, 3072, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 3M" },
|
||||
{ 6, 7, -1, -1, 23, 2, 6144, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 6M" },
|
||||
{ 6, 7, -1, -1, 23, 1, -1, -1, MOBILE_CORE_DUO , 0, 0, "Penryn (Core 2 Duo)" },
|
||||
{ 6, 7, -1, -1, 23, 2, 1024, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo)" },
|
||||
{ 6, 7, -1, -1, 23, 2, 3072, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 3M" },
|
||||
{ 6, 7, -1, -1, 23, 2, 6144, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 6M" },
|
||||
{ 6, 7, -1, -1, 23, 4, 2048, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 2M"},
|
||||
{ 6, 7, -1, -1, 23, 4, 3072, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 3M"},
|
||||
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 6M"},
|
||||
|
||||
/* Core microarchitecture-based Xeons: */
|
||||
{ 6, 14, -1, -1, 14, 1, -1, -1, NC, XEON_ , 0, "Xeon LV" },
|
||||
{ 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _5100, "Xeon (Woodcrest)" },
|
||||
{ 6, 15, -1, -1, 15, 2, 2048, -1, NC, XEON_ , _3000, "Xeon (Conroe/2M)" },
|
||||
{ 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _3000, "Xeon (Conroe/4M)" },
|
||||
{ 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , X3200, "Xeon (Kentsfield)" },
|
||||
{ 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , _5300, "Xeon (Clovertown)" },
|
||||
{ 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _3100, "Xeon (Wolfdale)" },
|
||||
{ 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _5200, "Xeon (Wolfdale DP)" },
|
||||
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , _5400, "Xeon (Harpertown)" },
|
||||
{ 6, 7, -1, -1, 23, 4, 3072, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/3M)" },
|
||||
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/6M)" },
|
||||
|
||||
/* Nehalem CPUs (45nm): */
|
||||
{ 6, 10, -1, -1, 26, 4, -1, -1, GAINESTOWN, XEON_ , 0, "Gainestown (Xeon)" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, 4096, GAINESTOWN, XEON_ , 0, "Gainestown 4M (Xeon)" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, 8192, GAINESTOWN, XEON_ , 0, "Gainestown 8M (Xeon)" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, -1, NC, XEON_|_7 , 0, "Bloomfield (Xeon)" },
|
||||
{ 6, 10, -1, -1, 26, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Bloomfield (Core i7)" },
|
||||
{ 6, 10, -1, -1, 30, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Lynnfield (Core i7)" },
|
||||
{ 6, 5, -1, -1, 37, 4, -1, 8192, NC, CORE_|_I_|_5 , 0, "Lynnfield (Core i5)" },
|
||||
|
||||
/* Westmere CPUs (32nm): */
|
||||
{ 6, 5, -1, -1, 37, 2, -1, -1, NC, 0 , 0, "Unknown Core i3/i5" },
|
||||
{ 6, 12, -1, -1, 44, -1, -1, -1, WESTMERE, XEON_ , 0, "Westmere (Xeon)" },
|
||||
{ 6, 12, -1, -1, 44, -1, -1, 12288, WESTMERE, XEON_ , 0, "Gulftown (Xeon)" },
|
||||
{ 6, 12, -1, -1, 44, 4, -1, 12288, NC, CORE_|_I_|_7 , 0, "Gulftown (Core i7)" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_5 , 0, "Clarkdale (Core i5)" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_3 , 0, "Clarkdale (Core i3)" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_7 , 0, "Arrandale (Core i7)" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_5 , 0, "Arrandale (Core i5)" },
|
||||
{ 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_3 , 0, "Arrandale (Core i3)" },
|
||||
|
||||
/* Sandy Bridge CPUs (32nm): */
|
||||
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, 0 , 0, "Unknown Sandy Bridge" },
|
||||
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge (Xeon)" },
|
||||
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, CORE_|_I_|_7 , 0, "Sandy Bridge (Core i7)" },
|
||||
{ 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Sandy Bridge (Core i7)" },
|
||||
{ 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Sandy Bridge (Core i5)" },
|
||||
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Sandy Bridge (Core i3)" },
|
||||
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, PENTIUM_ , 0, "Sandy Bridge (Pentium)" },
|
||||
{ 6, 10, -1, -1, 42, 1, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
|
||||
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
|
||||
{ 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_|_I_|_3 , 0, "Sandy Bridge-E" },
|
||||
{ 6, 13, -1, -1, 45, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge-E (Xeon)" },
|
||||
|
||||
/* Ivy Bridge CPUs (22nm): */
|
||||
{ 6, 10, -1, -1, 58, -1, -1, -1, NC, XEON_ , 0, "Ivy Bridge (Xeon)" },
|
||||
{ 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Ivy Bridge (Core i7)" },
|
||||
{ 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Ivy Bridge (Core i5)" },
|
||||
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Ivy Bridge (Core i3)" },
|
||||
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, PENTIUM_ , 0, "Ivy Bridge (Pentium)" },
|
||||
{ 6, 10, -1, -1, 58, 1, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
|
||||
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
|
||||
{ 6, 14, -1, -1, 62, -1, -1, -1, NC, 0 , 0, "Ivy Bridge-E" },
|
||||
|
||||
/* Haswell CPUs (22nm): */
|
||||
{ 6, 12, -1, -1, 60, -1, -1, -1, NC, XEON_ , 0, "Haswell (Xeon)" },
|
||||
{ 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" },
|
||||
{ 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" },
|
||||
{ 6, 6, -1, -1, 70, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" },
|
||||
{ 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" },
|
||||
{ 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" },
|
||||
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" },
|
||||
{ 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" },
|
||||
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Haswell (Core i3)" },
|
||||
{ 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Haswell (Core i3)" },
|
||||
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, PENTIUM_ , 0, "Haswell (Pentium)" },
|
||||
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
|
||||
{ 6, 12, -1, -1, 60, 1, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
|
||||
{ 6, 15, -1, -1, 63, -1, -1, -1, NC, 0 , 0, "Haswell-E" },
|
||||
|
||||
/* Broadwell CPUs (14nm): */
|
||||
{ 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell (Core i7)" },
|
||||
{ 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell (Core i5)" },
|
||||
{ 6, 13, -1, -1, 61, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-U (Core i7)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-U (Core i7)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-U (Core i5)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Broadwell-U (Core i3)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, PENTIUM_ , 0, "Broadwell-U (Pentium)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CELERON_ , 0, "Broadwell-U (Celeron)" },
|
||||
{ 6, 13, -1, -1, 61, 2, -1, -1, NA, 0 , 0, "Broadwell-U (Core M)" },
|
||||
{ 6, 15, -1, -1, 79, -1, -1, -1, NC, XEON_ , 0, "Broadwell-E (Xeon)" },
|
||||
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Broadwell-E (Core i3)" },
|
||||
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-E (Core i5)" },
|
||||
{ 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-E (Core i5)" },
|
||||
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" },
|
||||
{ 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" },
|
||||
|
||||
/* Skylake CPUs (14nm): */
|
||||
{ 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" },
|
||||
{ 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Skylake (Core i7)" },
|
||||
{ 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Skylake (Core i5)" },
|
||||
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Skylake (Core i3)" },
|
||||
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
|
||||
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
|
||||
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
|
||||
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
|
||||
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_7 , 0, "Skylake (Core m7)" },
|
||||
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_5 , 0, "Skylake (Core m5)" },
|
||||
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Skylake (Core m3)" },
|
||||
|
||||
/* Kaby Lake CPUs (14nm): */
|
||||
{ 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake (Core i7)" },
|
||||
{ 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake (Core i5)" },
|
||||
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Kaby Lake (Core i3)" },
|
||||
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake (Pentium)" },
|
||||
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake (Celeron)" },
|
||||
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Kaby Lake (Core m3)" },
|
||||
|
||||
/* Itaniums */
|
||||
{ 7, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Itanium" },
|
||||
{ 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Itanium 2" },
|
||||
};
|
||||
|
||||
|
||||
static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||
{
|
||||
const struct feature_map_t matchtable_edx1[] = {
|
||||
|
@ -558,8 +273,6 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
|
|||
else if (level == 4 && typenumber == 3)
|
||||
type = L4;
|
||||
else {
|
||||
warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber);
|
||||
warnf("deterministic_cache: recognize cache type\n");
|
||||
continue;
|
||||
}
|
||||
ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1;
|
||||
|
@ -681,7 +394,6 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
|
|||
code = matchtable[i].c;
|
||||
break;
|
||||
}
|
||||
debugf(2, "intel matchtable result is %d\n", code);
|
||||
if (bits & XEON_) {
|
||||
if (match_pattern(bs, "W35##") || match_pattern(bs, "[ELXW]75##"))
|
||||
bits |= _7;
|
||||
|
@ -743,65 +455,6 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
|
|||
return result;
|
||||
}
|
||||
|
||||
static intel_model_t get_model_code(struct cpu_id_t* data)
|
||||
{
|
||||
int i = 0;
|
||||
int l = (int) strlen(data->brand_str);
|
||||
const char *bs = data->brand_str;
|
||||
int mod_flags = 0, model_no = 0, ndigs = 0;
|
||||
/* If the CPU is a Core ix, then just return the model number generation: */
|
||||
if ((i = match_pattern(bs, "Core(TM) i[357]")) != 0) {
|
||||
i += 11;
|
||||
if (i + 4 >= l) return UNKNOWN;
|
||||
if (bs[i] == '2') return _2xxx;
|
||||
if (bs[i] == '3') return _3xxx;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
/* For Core2-based Xeons: */
|
||||
while (i < l - 3) {
|
||||
if (bs[i] == 'C' && bs[i+1] == 'P' && bs[i+2] == 'U')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i >= l - 3) return UNKNOWN;
|
||||
i += 3;
|
||||
while (i < l - 4 && bs[i] == ' ') i++;
|
||||
if (i >= l - 4) return UNKNOWN;
|
||||
while (i < l - 4 && !isdigit(bs[i])) {
|
||||
if (bs[i] >= 'A' && bs[i] <= 'Z')
|
||||
mod_flags |= (1 << (bs[i] - 'A'));
|
||||
i++;
|
||||
}
|
||||
if (i >= l - 4) return UNKNOWN;
|
||||
while (isdigit(bs[i])) {
|
||||
ndigs++;
|
||||
model_no = model_no * 10 + (int) (bs[i] - '0');
|
||||
i++;
|
||||
}
|
||||
if (ndigs != 4) return UNKNOWN;
|
||||
#define HAVE(ch, flags) ((flags & (1 << ((int)(ch-'A')))) != 0)
|
||||
switch (model_no / 100) {
|
||||
case 30: return _3000;
|
||||
case 31: return _3100;
|
||||
case 32:
|
||||
{
|
||||
return (HAVE('X', mod_flags)) ? X3200 : _3200;
|
||||
}
|
||||
case 33:
|
||||
{
|
||||
return (HAVE('X', mod_flags)) ? X3300 : _3300;
|
||||
}
|
||||
case 51: return _5100;
|
||||
case 52: return _5200;
|
||||
case 53: return _5300;
|
||||
case 54: return _5400;
|
||||
default:
|
||||
return UNKNOWN;
|
||||
}
|
||||
#undef HAVE
|
||||
}
|
||||
|
||||
static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||
{
|
||||
struct cpu_epc_t epc;
|
||||
|
@ -828,13 +481,11 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c
|
|||
for (i = 0; i < 1000000; i++) {
|
||||
epc = cpuid_get_epc(i, raw);
|
||||
if (epc.length == 0) {
|
||||
debugf(2, "SGX: epc section request for %d returned null, no more EPC sections.\n", i);
|
||||
data->sgx.num_epc_sections = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (data->sgx.num_epc_sections == -1) {
|
||||
debugf(1, "SGX: warning: seems to be infinitude of EPC sections.\n");
|
||||
data->sgx.num_epc_sections = 1000000;
|
||||
}
|
||||
}
|
||||
|
@ -867,9 +518,6 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw)
|
|||
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
|
||||
{
|
||||
intel_code_and_bits_t brand;
|
||||
intel_model_t model_code;
|
||||
int i;
|
||||
char* brand_code_str = NULL;
|
||||
|
||||
load_intel_features(raw, data);
|
||||
if (raw->basic_cpuid[0][0] >= 4) {
|
||||
|
@ -881,38 +529,14 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, stru
|
|||
decode_intel_number_of_cores(raw, data);
|
||||
|
||||
brand = get_brand_code_and_bits(data);
|
||||
model_code = get_model_code(data);
|
||||
for (i = 0; i < COUNT_OF(intel_bcode_str); i++) {
|
||||
if (brand.code == intel_bcode_str[i].code) {
|
||||
brand_code_str = intel_bcode_str[i].str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (brand_code_str)
|
||||
debugf(2, "Detected Intel brand code: %d (%s)\n", brand.code, brand_code_str);
|
||||
else
|
||||
debugf(2, "Detected Intel brand code: %d\n", brand.code);
|
||||
if (brand.bits) {
|
||||
debugf(2, "Detected Intel bits: ");
|
||||
debug_print_lbits(2, brand.bits);
|
||||
}
|
||||
debugf(2, "Detected Intel model code: %d\n", model_code);
|
||||
|
||||
internal->code.intel = brand.code;
|
||||
internal->bits = brand.bits;
|
||||
|
||||
if (data->flags[CPU_FEATURE_SGX]) {
|
||||
debugf(2, "SGX seems to be present, decoding...\n");
|
||||
// if SGX is indicated by the CPU, verify its presence:
|
||||
decode_intel_sgx_features(raw, data);
|
||||
}
|
||||
|
||||
internal->score = match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data,
|
||||
brand.code, brand.bits, model_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cpuid_get_list_intel(struct cpu_list_t* list)
|
||||
{
|
||||
generic_get_cpu_list(cpudb_intel, COUNT_OF(cpudb_intel), list);
|
||||
}
|
||||
|
|
1
src/3rdparty/libcpuid/recog_intel.h
vendored
1
src/3rdparty/libcpuid/recog_intel.h
vendored
|
@ -27,6 +27,5 @@
|
|||
#define __RECOG_INTEL_H__
|
||||
|
||||
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
|
||||
void cpuid_get_list_intel(struct cpu_list_t* list);
|
||||
|
||||
#endif /*__RECOG_INTEL_H__*/
|
||||
|
|
Loading…
Reference in a new issue