mirror of
https://github.com/anrieff/libcpuid
synced 2024-12-16 16:35:45 +00:00
Use constant for registers name
It helps when reading technical documentation and it avoids 'magic values'
This commit is contained in:
parent
0b05f45e03
commit
b23145144f
5 changed files with 110 additions and 101 deletions
|
@ -227,19 +227,19 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da
|
||||||
const struct feature_map_t matchtable_edx87[] = {
|
const struct feature_map_t matchtable_edx87[] = {
|
||||||
{ 8, CPU_FEATURE_CONSTANT_TSC },
|
{ 8, CPU_FEATURE_CONSTANT_TSC },
|
||||||
};
|
};
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
if (raw->basic_cpuid[0][EAX] >= 1) {
|
||||||
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][EDX], data);
|
||||||
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][ECX], data);
|
||||||
}
|
}
|
||||||
if (raw->basic_cpuid[0][0] >= 7) {
|
if (raw->basic_cpuid[0][EAX] >= 7) {
|
||||||
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][1], data);
|
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][EBX], data);
|
||||||
}
|
}
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
if (raw->ext_cpuid[0][EAX] >= 0x80000001) {
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][EDX], data);
|
||||||
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][ECX], data);
|
||||||
}
|
}
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000007) {
|
if (raw->ext_cpuid[0][EAX] >= 0x80000007) {
|
||||||
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data);
|
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][EDX], data);
|
||||||
}
|
}
|
||||||
if (data->flags[CPU_FEATURE_SSE]) {
|
if (data->flags[CPU_FEATURE_SSE]) {
|
||||||
/* apply guesswork to check if the SSE unit width is 128 bit */
|
/* apply guesswork to check if the SSE unit width is 128 bit */
|
||||||
|
@ -300,20 +300,20 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat
|
||||||
|
|
||||||
if (data->vendor == VENDOR_UNKNOWN)
|
if (data->vendor == VENDOR_UNKNOWN)
|
||||||
return set_error(ERR_CPU_UNKN);
|
return set_error(ERR_CPU_UNKN);
|
||||||
basic = raw->basic_cpuid[0][0];
|
basic = raw->basic_cpuid[0][EAX];
|
||||||
if (basic >= 1) {
|
if (basic >= 1) {
|
||||||
data->family = (raw->basic_cpuid[1][0] >> 8) & 0xf;
|
data->family = (raw->basic_cpuid[1][EAX] >> 8) & 0xf;
|
||||||
data->model = (raw->basic_cpuid[1][0] >> 4) & 0xf;
|
data->model = (raw->basic_cpuid[1][EAX] >> 4) & 0xf;
|
||||||
data->stepping = raw->basic_cpuid[1][0] & 0xf;
|
data->stepping = raw->basic_cpuid[1][EAX] & 0xf;
|
||||||
xmodel = (raw->basic_cpuid[1][0] >> 16) & 0xf;
|
xmodel = (raw->basic_cpuid[1][EAX] >> 16) & 0xf;
|
||||||
xfamily = (raw->basic_cpuid[1][0] >> 20) & 0xff;
|
xfamily = (raw->basic_cpuid[1][EAX] >> 20) & 0xff;
|
||||||
if (data->vendor == VENDOR_AMD && data->family < 0xf)
|
if (data->vendor == VENDOR_AMD && data->family < 0xf)
|
||||||
data->ext_family = data->family;
|
data->ext_family = data->family;
|
||||||
else
|
else
|
||||||
data->ext_family = data->family + xfamily;
|
data->ext_family = data->family + xfamily;
|
||||||
data->ext_model = data->model + (xmodel << 4);
|
data->ext_model = data->model + (xmodel << 4);
|
||||||
}
|
}
|
||||||
ext = raw->ext_cpuid[0][0] - 0x8000000;
|
ext = raw->ext_cpuid[0][EAX] - 0x8000000;
|
||||||
|
|
||||||
/* obtain the brand string, if present: */
|
/* obtain the brand string, if present: */
|
||||||
if (ext >= 4) {
|
if (ext >= 4) {
|
||||||
|
@ -388,26 +388,26 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
||||||
cpu_exec_cpuid(0x80000000 + i, data->ext_cpuid[i]);
|
cpu_exec_cpuid(0x80000000 + i, data->ext_cpuid[i]);
|
||||||
for (i = 0; i < MAX_INTELFN4_LEVEL; i++) {
|
for (i = 0; i < MAX_INTELFN4_LEVEL; i++) {
|
||||||
memset(data->intel_fn4[i], 0, sizeof(data->intel_fn4[i]));
|
memset(data->intel_fn4[i], 0, sizeof(data->intel_fn4[i]));
|
||||||
data->intel_fn4[i][0] = 4;
|
data->intel_fn4[i][EAX] = 4;
|
||||||
data->intel_fn4[i][2] = i;
|
data->intel_fn4[i][ECX] = i;
|
||||||
cpu_exec_cpuid_ext(data->intel_fn4[i]);
|
cpu_exec_cpuid_ext(data->intel_fn4[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
||||||
memset(data->intel_fn11[i], 0, sizeof(data->intel_fn11[i]));
|
memset(data->intel_fn11[i], 0, sizeof(data->intel_fn11[i]));
|
||||||
data->intel_fn11[i][0] = 11;
|
data->intel_fn11[i][EAX] = 11;
|
||||||
data->intel_fn11[i][2] = i;
|
data->intel_fn11[i][ECX] = i;
|
||||||
cpu_exec_cpuid_ext(data->intel_fn11[i]);
|
cpu_exec_cpuid_ext(data->intel_fn11[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) {
|
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) {
|
||||||
memset(data->intel_fn12h[i], 0, sizeof(data->intel_fn12h[i]));
|
memset(data->intel_fn12h[i], 0, sizeof(data->intel_fn12h[i]));
|
||||||
data->intel_fn12h[i][0] = 0x12;
|
data->intel_fn12h[i][EAX] = 0x12;
|
||||||
data->intel_fn12h[i][2] = i;
|
data->intel_fn12h[i][ECX] = i;
|
||||||
cpu_exec_cpuid_ext(data->intel_fn12h[i]);
|
cpu_exec_cpuid_ext(data->intel_fn12h[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) {
|
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) {
|
||||||
memset(data->intel_fn14h[i], 0, sizeof(data->intel_fn14h[i]));
|
memset(data->intel_fn14h[i], 0, sizeof(data->intel_fn14h[i]));
|
||||||
data->intel_fn14h[i][0] = 0x14;
|
data->intel_fn14h[i][EAX] = 0x14;
|
||||||
data->intel_fn14h[i][2] = i;
|
data->intel_fn14h[i][ECX] = i;
|
||||||
cpu_exec_cpuid_ext(data->intel_fn14h[i]);
|
cpu_exec_cpuid_ext(data->intel_fn14h[i]);
|
||||||
}
|
}
|
||||||
return set_error(ERR_OK);
|
return set_error(ERR_OK);
|
||||||
|
@ -427,28 +427,28 @@ int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
|
||||||
fprintf(f, "version=%s\n", VERSION);
|
fprintf(f, "version=%s\n", VERSION);
|
||||||
for (i = 0; i < MAX_CPUID_LEVEL; i++)
|
for (i = 0; i < MAX_CPUID_LEVEL; i++)
|
||||||
fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", 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][EAX], data->basic_cpuid[i][EBX],
|
||||||
data->basic_cpuid[i][2], data->basic_cpuid[i][3]);
|
data->basic_cpuid[i][ECX], data->basic_cpuid[i][EDX]);
|
||||||
for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++)
|
for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++)
|
||||||
fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", 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][EAX], data->ext_cpuid[i][EBX],
|
||||||
data->ext_cpuid[i][2], data->ext_cpuid[i][3]);
|
data->ext_cpuid[i][ECX], data->ext_cpuid[i][EDX]);
|
||||||
for (i = 0; i < MAX_INTELFN4_LEVEL; i++)
|
for (i = 0; i < MAX_INTELFN4_LEVEL; i++)
|
||||||
fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", 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][EAX], data->intel_fn4[i][EBX],
|
||||||
data->intel_fn4[i][2], data->intel_fn4[i][3]);
|
data->intel_fn4[i][ECX], data->intel_fn4[i][EDX]);
|
||||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++)
|
for (i = 0; i < MAX_INTELFN11_LEVEL; i++)
|
||||||
fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", 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][EAX], data->intel_fn11[i][EBX],
|
||||||
data->intel_fn11[i][2], data->intel_fn11[i][3]);
|
data->intel_fn11[i][ECX], data->intel_fn11[i][EDX]);
|
||||||
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++)
|
for (i = 0; i < MAX_INTELFN12H_LEVEL; i++)
|
||||||
fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", 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][EAX], data->intel_fn12h[i][EBX],
|
||||||
data->intel_fn12h[i][2], data->intel_fn12h[i][3]);
|
data->intel_fn12h[i][ECX], data->intel_fn12h[i][EDX]);
|
||||||
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++)
|
for (i = 0; i < MAX_INTELFN14H_LEVEL; i++)
|
||||||
fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", 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][EAX], data->intel_fn14h[i][EBX],
|
||||||
data->intel_fn14h[i][2], data->intel_fn14h[i][3]);
|
data->intel_fn14h[i][ECX], data->intel_fn14h[i][EDX]);
|
||||||
|
|
||||||
if (strcmp(filename, ""))
|
if (strcmp(filename, ""))
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
|
@ -126,31 +126,31 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
struct cpu_raw_data_t {
|
struct cpu_raw_data_t {
|
||||||
/** contains results of CPUID for eax = 0, 1, ...*/
|
/** contains results of CPUID for eax = 0, 1, ...*/
|
||||||
uint32_t basic_cpuid[MAX_CPUID_LEVEL][4];
|
uint32_t basic_cpuid[MAX_CPUID_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
/** contains results of CPUID for eax = 0x80000000, 0x80000001, ...*/
|
/** contains results of CPUID for eax = 0x80000000, 0x80000001, ...*/
|
||||||
uint32_t ext_cpuid[MAX_EXT_CPUID_LEVEL][4];
|
uint32_t ext_cpuid[MAX_EXT_CPUID_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
/** when the CPU is intel and it supports deterministic cache
|
/** when the CPU is intel and it supports deterministic cache
|
||||||
information: this contains the results of CPUID for eax = 4
|
information: this contains the results of CPUID for eax = 4
|
||||||
and ecx = 0, 1, ... */
|
and ecx = 0, 1, ... */
|
||||||
uint32_t intel_fn4[MAX_INTELFN4_LEVEL][4];
|
uint32_t intel_fn4[MAX_INTELFN4_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
/** when the CPU is intel and it supports leaf 0Bh (Extended Topology
|
/** when the CPU is intel and it supports leaf 0Bh (Extended Topology
|
||||||
enumeration leaf), this stores the result of CPUID with
|
enumeration leaf), this stores the result of CPUID with
|
||||||
eax = 11 and ecx = 0, 1, 2... */
|
eax = 11 and ecx = 0, 1, 2... */
|
||||||
uint32_t intel_fn11[MAX_INTELFN11_LEVEL][4];
|
uint32_t intel_fn11[MAX_INTELFN11_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
/** when the CPU is intel and supports leaf 12h (SGX enumeration leaf),
|
/** when the CPU is intel and supports leaf 12h (SGX enumeration leaf),
|
||||||
* this stores the result of CPUID with eax = 0x12 and
|
* this stores the result of CPUID with eax = 0x12 and
|
||||||
* ecx = 0, 1, 2... */
|
* ecx = 0, 1, 2... */
|
||||||
uint32_t intel_fn12h[MAX_INTELFN12H_LEVEL][4];
|
uint32_t intel_fn12h[MAX_INTELFN12H_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
/** when the CPU is intel and supports leaf 14h (Intel Processor Trace
|
/** when the CPU is intel and supports leaf 14h (Intel Processor Trace
|
||||||
* capabilities leaf).
|
* capabilities leaf).
|
||||||
* this stores the result of CPUID with eax = 0x12 and
|
* this stores the result of CPUID with eax = 0x12 and
|
||||||
* ecx = 0, 1, 2... */
|
* ecx = 0, 1, 2... */
|
||||||
uint32_t intel_fn14h[MAX_INTELFN14H_LEVEL][4];
|
uint32_t intel_fn14h[MAX_INTELFN14H_LEVEL][NUM_REGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -44,4 +44,13 @@
|
||||||
#define CPU_HINTS_MAX 16
|
#define CPU_HINTS_MAX 16
|
||||||
#define SGX_FLAGS_MAX 14
|
#define SGX_FLAGS_MAX 14
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EAX,
|
||||||
|
EBX,
|
||||||
|
ECX,
|
||||||
|
EDX,
|
||||||
|
/* termination: */
|
||||||
|
NUM_REGS,
|
||||||
|
} cpu_registers_t;
|
||||||
|
|
||||||
#endif /* __LIBCPUID_CONSTANTS_H__ */
|
#endif /* __LIBCPUID_CONSTANTS_H__ */
|
||||||
|
|
|
@ -344,22 +344,22 @@ static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||||
{ 11, CPU_FEATURE_PFI },
|
{ 11, CPU_FEATURE_PFI },
|
||||||
{ 12, CPU_FEATURE_PA },
|
{ 12, CPU_FEATURE_PA },
|
||||||
};
|
};
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
if (raw->ext_cpuid[0][EAX] >= 0x80000001) {
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][EDX], data);
|
||||||
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][ECX], data);
|
||||||
}
|
}
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000007)
|
if (raw->ext_cpuid[0][EAX] >= 0x80000007)
|
||||||
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data);
|
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][EDX], data);
|
||||||
if (raw->ext_cpuid[0][0] >= 0x8000001a) {
|
if (raw->ext_cpuid[0][EAX] >= 0x8000001a) {
|
||||||
/* We have the extended info about SSE unit size
|
/* We have the extended info about SSE unit size
|
||||||
Extracted from BKDG, about CPUID_Fn8000001A_EAX [Performance Optimization Identifiers] (Core::X86::Cpuid::PerfOptId):
|
Extracted from BKDG, about CPUID_Fn8000001A_EAX [Performance Optimization Identifiers] (Core::X86::Cpuid::PerfOptId):
|
||||||
- bit 2: FP256
|
- bit 2: FP256
|
||||||
- bit 1: MOVU
|
- bit 1: MOVU
|
||||||
- bit 0: FP128 */
|
- bit 0: FP128 */
|
||||||
data->detection_hints[CPU_HINT_SSE_SIZE_AUTH] = 1;
|
data->detection_hints[CPU_HINT_SSE_SIZE_AUTH] = 1;
|
||||||
if ((raw->ext_cpuid[0x1a][0] >> 2) & 1)
|
if ((raw->ext_cpuid[0x1a][EAX] >> 2) & 1)
|
||||||
data->sse_size = 256;
|
data->sse_size = 256;
|
||||||
else if ((raw->ext_cpuid[0x1a][0]) & 1)
|
else if ((raw->ext_cpuid[0x1a][EAX]) & 1)
|
||||||
data->sse_size = 128;
|
data->sse_size = 128;
|
||||||
else
|
else
|
||||||
data->sse_size = 64;
|
data->sse_size = 64;
|
||||||
|
@ -372,26 +372,26 @@ static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* d
|
||||||
const int assoc_table[16] = {
|
const int assoc_table[16] = {
|
||||||
0, 1, 2, 0, 4, 0, 8, 0, 16, 16, 32, 48, 64, 96, 128, 255
|
0, 1, 2, 0, 4, 0, 8, 0, 16, 16, 32, 48, 64, 96, 128, 255
|
||||||
};
|
};
|
||||||
unsigned n = raw->ext_cpuid[0][0];
|
unsigned n = raw->ext_cpuid[0][EAX];
|
||||||
|
|
||||||
if (n >= 0x80000005) {
|
if (n >= 0x80000005) {
|
||||||
data->l1_data_cache = (raw->ext_cpuid[5][2] >> 24) & 0xff;
|
data->l1_data_cache = (raw->ext_cpuid[5][ECX] >> 24) & 0xff;
|
||||||
data->l1_assoc = (raw->ext_cpuid[5][2] >> 16) & 0xff;
|
data->l1_assoc = (raw->ext_cpuid[5][ECX] >> 16) & 0xff;
|
||||||
data->l1_cacheline = (raw->ext_cpuid[5][2]) & 0xff;
|
data->l1_cacheline = (raw->ext_cpuid[5][ECX]) & 0xff;
|
||||||
data->l1_instruction_cache = (raw->ext_cpuid[5][3] >> 24) & 0xff;
|
data->l1_instruction_cache = (raw->ext_cpuid[5][EDX] >> 24) & 0xff;
|
||||||
}
|
}
|
||||||
if (n >= 0x80000006) {
|
if (n >= 0x80000006) {
|
||||||
data->l2_cache = (raw->ext_cpuid[6][2] >> 16) & 0xffff;
|
data->l2_cache = (raw->ext_cpuid[6][ECX] >> 16) & 0xffff;
|
||||||
data->l2_assoc = assoc_table[(raw->ext_cpuid[6][2] >> 12) & 0xf];
|
data->l2_assoc = assoc_table[(raw->ext_cpuid[6][ECX] >> 12) & 0xf];
|
||||||
data->l2_cacheline = (raw->ext_cpuid[6][2]) & 0xff;
|
data->l2_cacheline = (raw->ext_cpuid[6][ECX]) & 0xff;
|
||||||
|
|
||||||
l3_result = (raw->ext_cpuid[6][3] >> 18);
|
l3_result = (raw->ext_cpuid[6][EDX] >> 18);
|
||||||
if (l3_result > 0) {
|
if (l3_result > 0) {
|
||||||
l3_result = 512 * l3_result; /* AMD spec says it's a range,
|
l3_result = 512 * l3_result; /* AMD spec says it's a range,
|
||||||
but we take the lower bound */
|
but we take the lower bound */
|
||||||
data->l3_cache = l3_result;
|
data->l3_cache = l3_result;
|
||||||
data->l3_assoc = assoc_table[(raw->ext_cpuid[6][3] >> 12) & 0xf];
|
data->l3_assoc = assoc_table[(raw->ext_cpuid[6][EDX] >> 12) & 0xf];
|
||||||
data->l3_cacheline = (raw->ext_cpuid[6][3]) & 0xff;
|
data->l3_cacheline = (raw->ext_cpuid[6][EDX]) & 0xff;
|
||||||
} else {
|
} else {
|
||||||
data->l3_cache = 0;
|
data->l3_cache = 0;
|
||||||
}
|
}
|
||||||
|
@ -402,21 +402,21 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
|
||||||
{
|
{
|
||||||
int logical_cpus = -1, num_cores = -1;
|
int logical_cpus = -1, num_cores = -1;
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
if (raw->basic_cpuid[0][EAX] >= 1) {
|
||||||
logical_cpus = (raw->basic_cpuid[1][1] >> 16) & 0xff;
|
logical_cpus = (raw->basic_cpuid[1][EBX] >> 16) & 0xff;
|
||||||
if (raw->ext_cpuid[0][0] >= 8) {
|
if (raw->ext_cpuid[0][EAX] >= 8) {
|
||||||
num_cores = 1 + (raw->ext_cpuid[8][2] & 0xff);
|
num_cores = 1 + (raw->ext_cpuid[8][ECX] & 0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->flags[CPU_FEATURE_HT]) {
|
if (data->flags[CPU_FEATURE_HT]) {
|
||||||
if (num_cores > 1) {
|
if (num_cores > 1) {
|
||||||
if ((data->ext_family >= 23) && (raw->ext_cpuid[0][0] >= 30))
|
if ((data->ext_family >= 23) && (raw->ext_cpuid[0][EAX] >= 30))
|
||||||
/* Ryzen 3 has SMT flag, but in fact cores count is equal to threads count.
|
/* Ryzen 3 has SMT flag, but in fact cores count is equal to threads count.
|
||||||
Ryzen 5/7 reports twice as many "real" cores (e.g. 16 cores instead of 8) because of SMT. */
|
Ryzen 5/7 reports twice as many "real" cores (e.g. 16 cores instead of 8) because of SMT. */
|
||||||
/* On PPR 17h, page 82:
|
/* On PPR 17h, page 82:
|
||||||
CPUID_Fn8000001E_EBX [Core Identifiers][15:8] is ThreadsPerCore
|
CPUID_Fn8000001E_EBX [Core Identifiers][15:8] is ThreadsPerCore
|
||||||
ThreadsPerCore: [...] The number of threads per core is ThreadsPerCore+1 */
|
ThreadsPerCore: [...] The number of threads per core is ThreadsPerCore+1 */
|
||||||
num_cores /= ((raw->ext_cpuid[30][1] >> 8) & 0xff) + 1;
|
num_cores /= ((raw->ext_cpuid[30][EBX] >> 8) & 0xff) + 1;
|
||||||
data->num_cores = num_cores;
|
data->num_cores = num_cores;
|
||||||
data->num_logical_cpus = logical_cpus;
|
data->num_logical_cpus = logical_cpus;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -434,17 +434,17 @@ static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* dat
|
||||||
const struct feature_map_t matchtable_ecx7[] = {
|
const struct feature_map_t matchtable_ecx7[] = {
|
||||||
{ 11, CPU_FEATURE_AVX512VNNI },
|
{ 11, CPU_FEATURE_AVX512VNNI },
|
||||||
};
|
};
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
if (raw->basic_cpuid[0][EAX] >= 1) {
|
||||||
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][EDX], data);
|
||||||
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][ECX], data);
|
||||||
}
|
}
|
||||||
if (raw->ext_cpuid[0][0] >= 1) {
|
if (raw->ext_cpuid[0][EAX] >= 1) {
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][EDX], data);
|
||||||
}
|
}
|
||||||
// detect TSX/AVX512:
|
// detect TSX/AVX512:
|
||||||
if (raw->basic_cpuid[0][0] >= 7) {
|
if (raw->basic_cpuid[0][EAX] >= 7) {
|
||||||
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][1], data);
|
match_features(matchtable_ebx7, COUNT_OF(matchtable_ebx7), raw->basic_cpuid[7][EBX], data);
|
||||||
match_features(matchtable_ecx7, COUNT_OF(matchtable_ecx7), raw->basic_cpuid[7][2], data);
|
match_features(matchtable_ecx7, COUNT_OF(matchtable_ecx7), raw->basic_cpuid[7][ECX], data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,9 +593,9 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
|
||||||
int ways, partitions, linesize, sets, size, level, typenumber;
|
int ways, partitions, linesize, sets, size, level, typenumber;
|
||||||
cache_type_t type;
|
cache_type_t type;
|
||||||
for (ecx = 0; ecx < MAX_INTELFN4_LEVEL; ecx++) {
|
for (ecx = 0; ecx < MAX_INTELFN4_LEVEL; ecx++) {
|
||||||
typenumber = raw->intel_fn4[ecx][0] & 0x1f;
|
typenumber = raw->intel_fn4[ecx][EAX] & 0x1f;
|
||||||
if (typenumber == 0) break;
|
if (typenumber == 0) break;
|
||||||
level = (raw->intel_fn4[ecx][0] >> 5) & 0x7;
|
level = (raw->intel_fn4[ecx][EAX] >> 5) & 0x7;
|
||||||
if (level == 1 && typenumber == 1)
|
if (level == 1 && typenumber == 1)
|
||||||
type = L1D;
|
type = L1D;
|
||||||
else if (level == 1 && typenumber == 2)
|
else if (level == 1 && typenumber == 2)
|
||||||
|
@ -611,10 +611,10 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
|
||||||
warnf("deterministic_cache: recognize cache type\n");
|
warnf("deterministic_cache: recognize cache type\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1;
|
ways = ((raw->intel_fn4[ecx][EBX] >> 22) & 0x3ff) + 1;
|
||||||
partitions = ((raw->intel_fn4[ecx][1] >> 12) & 0x3ff) + 1;
|
partitions = ((raw->intel_fn4[ecx][EBX] >> 12) & 0x3ff) + 1;
|
||||||
linesize = (raw->intel_fn4[ecx][1] & 0xfff) + 1;
|
linesize = (raw->intel_fn4[ecx][EBX] & 0xfff) + 1;
|
||||||
sets = raw->intel_fn4[ecx][2] + 1;
|
sets = raw->intel_fn4[ecx][ECX] + 1;
|
||||||
size = ways * partitions * linesize * sets / 1024;
|
size = ways * partitions * linesize * sets / 1024;
|
||||||
check_case(1, type, size, ways, linesize, data);
|
check_case(1, type, size, ways, linesize, data);
|
||||||
}
|
}
|
||||||
|
@ -625,13 +625,13 @@ static int decode_intel_extended_topology(struct cpu_raw_data_t* raw,
|
||||||
{
|
{
|
||||||
int i, level_type, num_smt = -1, num_core = -1;
|
int i, level_type, num_smt = -1, num_core = -1;
|
||||||
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
for (i = 0; i < MAX_INTELFN11_LEVEL; i++) {
|
||||||
level_type = (raw->intel_fn11[i][2] & 0xff00) >> 8;
|
level_type = (raw->intel_fn11[i][ECX] & 0xff00) >> 8;
|
||||||
switch (level_type) {
|
switch (level_type) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
num_smt = raw->intel_fn11[i][1] & 0xffff;
|
num_smt = raw->intel_fn11[i][EBX] & 0xffff;
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
num_core = raw->intel_fn11[i][1] & 0xffff;
|
num_core = raw->intel_fn11[i][EBX] & 0xffff;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -652,14 +652,14 @@ static void decode_intel_number_of_cores(struct cpu_raw_data_t* raw,
|
||||||
{
|
{
|
||||||
int logical_cpus = -1, num_cores = -1;
|
int logical_cpus = -1, num_cores = -1;
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 11) {
|
if (raw->basic_cpuid[0][EAX] >= 11) {
|
||||||
if (decode_intel_extended_topology(raw, data)) return;
|
if (decode_intel_extended_topology(raw, data)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
if (raw->basic_cpuid[0][EAX] >= 1) {
|
||||||
logical_cpus = (raw->basic_cpuid[1][1] >> 16) & 0xff;
|
logical_cpus = (raw->basic_cpuid[1][EBX] >> 16) & 0xff;
|
||||||
if (raw->basic_cpuid[0][0] >= 4) {
|
if (raw->basic_cpuid[0][EAX] >= 4) {
|
||||||
num_cores = 1 + ((raw->basic_cpuid[4][0] >> 26) & 0x3f);
|
num_cores = 1 + ((raw->basic_cpuid[4][EAX] >> 26) & 0x3f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data->flags[CPU_FEATURE_HT]) {
|
if (data->flags[CPU_FEATURE_HT]) {
|
||||||
|
@ -857,21 +857,21 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c
|
||||||
struct cpu_epc_t epc;
|
struct cpu_epc_t epc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (raw->basic_cpuid[0][0] < 0x12) return; // no 12h leaf
|
if (raw->basic_cpuid[0][EAX] < 0x12) return; // no 12h leaf
|
||||||
if (raw->basic_cpuid[0x12][0] == 0) return; // no sub-leafs available, probably it's disabled by BIOS
|
if (raw->basic_cpuid[0x12][EAX] == 0) return; // no sub-leafs available, probably it's disabled by BIOS
|
||||||
|
|
||||||
// decode sub-leaf 0:
|
// decode sub-leaf 0:
|
||||||
if (raw->basic_cpuid[0x12][0] & 1) data->sgx.flags[INTEL_SGX1] = 1;
|
if (raw->basic_cpuid[0x12][EAX] & 1) data->sgx.flags[INTEL_SGX1] = 1;
|
||||||
if (raw->basic_cpuid[0x12][0] & 2) data->sgx.flags[INTEL_SGX2] = 1;
|
if (raw->basic_cpuid[0x12][EAX] & 2) data->sgx.flags[INTEL_SGX2] = 1;
|
||||||
if (data->sgx.flags[INTEL_SGX1] || data->sgx.flags[INTEL_SGX2])
|
if (data->sgx.flags[INTEL_SGX1] || data->sgx.flags[INTEL_SGX2])
|
||||||
data->sgx.present = 1;
|
data->sgx.present = 1;
|
||||||
data->sgx.misc_select = raw->basic_cpuid[0x12][1];
|
data->sgx.misc_select = raw->basic_cpuid[0x12][EBX];
|
||||||
data->sgx.max_enclave_32bit = (raw->basic_cpuid[0x12][3] ) & 0xff;
|
data->sgx.max_enclave_32bit = (raw->basic_cpuid[0x12][EDX] ) & 0xff;
|
||||||
data->sgx.max_enclave_64bit = (raw->basic_cpuid[0x12][3] >> 8) & 0xff;
|
data->sgx.max_enclave_64bit = (raw->basic_cpuid[0x12][EDX] >> 8) & 0xff;
|
||||||
|
|
||||||
// decode sub-leaf 1:
|
// decode sub-leaf 1:
|
||||||
data->sgx.secs_attributes = raw->intel_fn12h[1][0] | (((uint64_t) raw->intel_fn12h[1][1]) << 32);
|
data->sgx.secs_attributes = raw->intel_fn12h[1][EAX] | (((uint64_t) raw->intel_fn12h[1][EBX]) << 32);
|
||||||
data->sgx.secs_xfrm = raw->intel_fn12h[1][2] | (((uint64_t) raw->intel_fn12h[1][3]) << 32);
|
data->sgx.secs_xfrm = raw->intel_fn12h[1][ECX] | (((uint64_t) raw->intel_fn12h[1][EDX]) << 32);
|
||||||
|
|
||||||
// decode higher-order subleafs, whenever present:
|
// decode higher-order subleafs, whenever present:
|
||||||
data->sgx.num_epc_sections = -1;
|
data->sgx.num_epc_sections = -1;
|
||||||
|
@ -922,10 +922,10 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, stru
|
||||||
char* brand_code_str = NULL;
|
char* brand_code_str = NULL;
|
||||||
|
|
||||||
load_intel_features(raw, data);
|
load_intel_features(raw, data);
|
||||||
if (raw->basic_cpuid[0][0] >= 4) {
|
if (raw->basic_cpuid[0][EAX] >= 4) {
|
||||||
/* Deterministic way is preferred, being more generic */
|
/* Deterministic way is preferred, being more generic */
|
||||||
decode_intel_deterministic_cache_info(raw, data);
|
decode_intel_deterministic_cache_info(raw, data);
|
||||||
} else if (raw->basic_cpuid[0][0] >= 2) {
|
} else if (raw->basic_cpuid[0][EAX] >= 2) {
|
||||||
decode_intel_oldstyle_cache_info(raw, data);
|
decode_intel_oldstyle_cache_info(raw, data);
|
||||||
}
|
}
|
||||||
decode_intel_number_of_cores(raw, data);
|
decode_intel_number_of_cores(raw, data);
|
||||||
|
|
Loading…
Reference in a new issue