1
0
Fork 0
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:
Xorg 2020-05-09 18:17:50 +02:00
parent 0b05f45e03
commit b23145144f
No known key found for this signature in database
GPG key ID: 1E55EE2EFF18BC1A
5 changed files with 110 additions and 101 deletions

View file

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

View file

@ -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];
}; };
/** /**

View file

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

View file

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

View file

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