mirror of
https://github.com/anrieff/libcpuid
synced 2024-12-16 16:35:45 +00:00
Re-fix L3 cache associativity detection on AMD Zen 2 CPUs
Previous commit: 848394ee46
This commit is contained in:
parent
b23145144f
commit
e562798cec
5 changed files with 37 additions and 3 deletions
|
@ -410,6 +410,12 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
|
||||||
data->intel_fn14h[i][ECX] = i;
|
data->intel_fn14h[i][ECX] = i;
|
||||||
cpu_exec_cpuid_ext(data->intel_fn14h[i]);
|
cpu_exec_cpuid_ext(data->intel_fn14h[i]);
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < MAX_AMDFN8000001DH_LEVEL; i++) {
|
||||||
|
memset(data->amd_fn8000001dh[i], 0, sizeof(data->amd_fn8000001dh[i]));
|
||||||
|
data->amd_fn8000001dh[i][EAX] = 0x8000001d;
|
||||||
|
data->amd_fn8000001dh[i][ECX] = i;
|
||||||
|
cpu_exec_cpuid_ext(data->amd_fn8000001dh[i]);
|
||||||
|
}
|
||||||
return set_error(ERR_OK);
|
return set_error(ERR_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,6 +455,10 @@ int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
|
||||||
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][EAX], data->intel_fn14h[i][EBX],
|
data->intel_fn14h[i][EAX], data->intel_fn14h[i][EBX],
|
||||||
data->intel_fn14h[i][ECX], data->intel_fn14h[i][EDX]);
|
data->intel_fn14h[i][ECX], data->intel_fn14h[i][EDX]);
|
||||||
|
for (i = 0; i < MAX_AMDFN8000001DH_LEVEL; i++)
|
||||||
|
fprintf(f, "amd_fn8000001dh[%d]=%08x %08x %08x %08x\n", i,
|
||||||
|
data->amd_fn8000001dh[i][EAX], data->amd_fn8000001dh[i][EBX],
|
||||||
|
data->amd_fn8000001dh[i][ECX], data->amd_fn8000001dh[i][EDX]);
|
||||||
|
|
||||||
if (strcmp(filename, ""))
|
if (strcmp(filename, ""))
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -499,6 +509,7 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename
|
||||||
syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_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_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);
|
syntax = syntax && parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized);
|
||||||
|
syntax = syntax && parse_token("amd_fn8000001dh", token, value, data->amd_fn8000001dh, MAX_AMDFN8000001DH_LEVEL, &recognized);
|
||||||
if (!syntax) {
|
if (!syntax) {
|
||||||
warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
|
warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
|
@ -151,6 +151,12 @@ struct cpu_raw_data_t {
|
||||||
* 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][NUM_REGS];
|
uint32_t intel_fn14h[MAX_INTELFN14H_LEVEL][NUM_REGS];
|
||||||
|
|
||||||
|
/** when the CPU is AMD and supports leaf 8000001Dh
|
||||||
|
* (topology information for the DC)
|
||||||
|
* this stores the result of CPUID with eax = 8000001Dh and
|
||||||
|
* ecx = 0, 1, 2... */
|
||||||
|
uint32_t amd_fn8000001dh[MAX_AMDFN8000001DH_LEVEL][NUM_REGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define MAX_INTELFN11_LEVEL 4
|
#define MAX_INTELFN11_LEVEL 4
|
||||||
#define MAX_INTELFN12H_LEVEL 4
|
#define MAX_INTELFN12H_LEVEL 4
|
||||||
#define MAX_INTELFN14H_LEVEL 4
|
#define MAX_INTELFN14H_LEVEL 4
|
||||||
|
#define MAX_AMDFN8000001DH_LEVEL 4
|
||||||
#define CPU_HINTS_MAX 16
|
#define CPU_HINTS_MAX 16
|
||||||
#define SGX_FLAGS_MAX 14
|
#define SGX_FLAGS_MAX 14
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
* for the workings of the internal library infrastructure.
|
* for the workings of the internal library infrastructure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define EXTRACTS_BIT(reg, bit) ((reg >> bit) & 0x1)
|
||||||
|
#define EXTRACTS_BITS(reg, highbit, lowbit) ((reg >> lowbit) & ((1ULL << (highbit - lowbit + 1)) - 1))
|
||||||
|
|
||||||
enum _common_codes_t {
|
enum _common_codes_t {
|
||||||
NA = 0,
|
NA = 0,
|
||||||
NC, /* No code */
|
NC, /* No code */
|
||||||
|
|
|
@ -368,7 +368,7 @@ static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||||
|
|
||||||
static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||||
{
|
{
|
||||||
int l3_result;
|
int l3_result, l3_assoc;
|
||||||
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
|
||||||
};
|
};
|
||||||
|
@ -389,9 +389,22 @@ static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* d
|
||||||
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 */
|
||||||
|
l3_assoc = (raw->ext_cpuid[6][EDX] >> 12) & 0xf;
|
||||||
data->l3_cache = l3_result;
|
data->l3_cache = l3_result;
|
||||||
data->l3_assoc = assoc_table[(raw->ext_cpuid[6][EDX] >> 12) & 0xf];
|
|
||||||
data->l3_cacheline = (raw->ext_cpuid[6][EDX]) & 0xff;
|
if(l3_assoc == 0x9) {
|
||||||
|
/* Since Zen 2, CPUID_Fn80000006_EDX[15:12] is invalid (0x9)
|
||||||
|
According to page 74 on
|
||||||
|
Processor Programming Reference (PPR) for AMD Family 17h Model 71h, Revision B0 Processors:
|
||||||
|
"There are insufficient available encodings to represent all possible L3
|
||||||
|
associativities. Please refer to Core::X86::Cpuid::CachePropEbx3[CacheNumWays]."
|
||||||
|
Note: we do not read CPUID_Fn80000001_ECX[22] (AKA TopologyExtensions) to allow retrocompatibility with existing tests */
|
||||||
|
data->l3_assoc = EXTRACTS_BITS(raw->amd_fn8000001dh[0x3][EBX], 31, 22) + 1; // Cache number of ways is CacheNumWays + 1
|
||||||
|
data->l3_cacheline = EXTRACTS_BITS(raw->amd_fn8000001dh[0x3][EBX], 11, 0) + 1; // Cache line size in bytes is CacheLineSize + 1
|
||||||
|
} else {
|
||||||
|
data->l3_assoc = assoc_table[l3_assoc];
|
||||||
|
data->l3_cacheline = (raw->ext_cpuid[6][EDX]) & 0xff;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
data->l3_cache = 0;
|
data->l3_cache = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue