mirror of
https://github.com/anrieff/libcpuid
synced 2024-12-16 16:35:45 +00:00
Add L1 Instruction Cache information
Some CPUs does not have the same associativity for L1D and L1I, as reported in X0rg/CPU-X#119 It adds l1_instruction_assoc and l1_instruction_cacheline in cpu_id_t To avoid confusing, also adds l1_data_assoc and l1_data_cacheline l1_assoc and l1_cacheline are leave untouched for backward compatibility
This commit is contained in:
parent
21e4b1f48e
commit
25d0614811
5 changed files with 54 additions and 15 deletions
|
@ -75,10 +75,12 @@ typedef enum {
|
|||
NEED_L3_SIZE,
|
||||
NEED_L4_SIZE,
|
||||
NEED_L1D_ASSOC,
|
||||
NEED_L1I_ASSOC,
|
||||
NEED_L2_ASSOC,
|
||||
NEED_L3_ASSOC,
|
||||
NEED_L4_ASSOC,
|
||||
NEED_L1D_CACHELINE,
|
||||
NEED_L1I_CACHELINE,
|
||||
NEED_L2_CACHELINE,
|
||||
NEED_L3_CACHELINE,
|
||||
NEED_L4_CACHELINE,
|
||||
|
@ -133,10 +135,12 @@ matchtable[] = {
|
|||
{ NEED_L3_SIZE , "--l3-cache" , 1},
|
||||
{ NEED_L4_SIZE , "--l4-cache" , 1},
|
||||
{ NEED_L1D_ASSOC , "--l1d-assoc" , 1},
|
||||
{ NEED_L1I_ASSOC , "--l1i-assoc" , 1},
|
||||
{ NEED_L2_ASSOC , "--l2-assoc" , 1},
|
||||
{ NEED_L3_ASSOC , "--l3-assoc" , 1},
|
||||
{ NEED_L4_ASSOC , "--l4-assoc" , 1},
|
||||
{ NEED_L1D_CACHELINE, "--l1d-cacheline", 1},
|
||||
{ NEED_L1I_CACHELINE, "--l1i-cacheline", 1},
|
||||
{ NEED_L2_CACHELINE , "--l2-cacheline" , 1},
|
||||
{ NEED_L3_CACHELINE , "--l3-cacheline" , 1},
|
||||
{ NEED_L4_CACHELINE , "--l4-cacheline" , 1},
|
||||
|
@ -391,7 +395,10 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
|
|||
fprintf(fout, "%d\n", data->l4_cache);
|
||||
break;
|
||||
case NEED_L1D_ASSOC:
|
||||
fprintf(fout, "%d\n", data->l1_assoc);
|
||||
fprintf(fout, "%d\n", data->l1_data_assoc);
|
||||
break;
|
||||
case NEED_L1I_ASSOC:
|
||||
fprintf(fout, "%d\n", data->l1_instruction_assoc);
|
||||
break;
|
||||
case NEED_L2_ASSOC:
|
||||
fprintf(fout, "%d\n", data->l2_assoc);
|
||||
|
@ -403,7 +410,10 @@ static void print_info(output_data_switch query, struct cpu_raw_data_t* raw,
|
|||
fprintf(fout, "%d\n", data->l4_assoc);
|
||||
break;
|
||||
case NEED_L1D_CACHELINE:
|
||||
fprintf(fout, "%d\n", data->l1_cacheline);
|
||||
fprintf(fout, "%d\n", data->l1_data_cacheline);
|
||||
break;
|
||||
case NEED_L1I_CACHELINE:
|
||||
fprintf(fout, "%d\n", data->l1_instruction_cacheline);
|
||||
break;
|
||||
case NEED_L2_CACHELINE:
|
||||
fprintf(fout, "%d\n", data->l2_cacheline);
|
||||
|
@ -654,11 +664,13 @@ int main(int argc, char** argv)
|
|||
fprintf(fout, " L2 cache : %d KB\n", data.l2_cache);
|
||||
fprintf(fout, " L3 cache : %d KB\n", data.l3_cache);
|
||||
fprintf(fout, " L4 cache : %d KB\n", data.l4_cache);
|
||||
fprintf(fout, " L1D assoc. : %d-way\n", data.l1_assoc);
|
||||
fprintf(fout, " L1D assoc. : %d-way\n", data.l1_data_assoc);
|
||||
fprintf(fout, " L1I assoc. : %d-way\n", data.l1_instruction_assoc);
|
||||
fprintf(fout, " L2 assoc. : %d-way\n", data.l2_assoc);
|
||||
fprintf(fout, " L3 assoc. : %d-way\n", data.l3_assoc);
|
||||
fprintf(fout, " L4 assoc. : %d-way\n", data.l4_assoc);
|
||||
fprintf(fout, " L1D line sz: %d bytes\n", data.l1_cacheline);
|
||||
fprintf(fout, " L1D line sz: %d bytes\n", data.l1_data_cacheline);
|
||||
fprintf(fout, " L1I line sz: %d bytes\n", data.l1_instruction_cacheline);
|
||||
fprintf(fout, " L2 line sz : %d bytes\n", data.l2_cacheline);
|
||||
fprintf(fout, " L3 line sz : %d bytes\n", data.l3_cacheline);
|
||||
fprintf(fout, " L4 line sz : %d bytes\n", data.l4_cacheline);
|
||||
|
|
|
@ -55,8 +55,8 @@ static void cpu_id_t_constructor(struct cpu_id_t* id)
|
|||
{
|
||||
memset(id, 0, sizeof(struct cpu_id_t));
|
||||
id->l1_data_cache = id->l1_instruction_cache = id->l2_cache = id->l3_cache = id->l4_cache = -1;
|
||||
id->l1_assoc = id->l2_assoc = id->l3_assoc = id->l4_assoc = -1;
|
||||
id->l1_cacheline = id->l2_cacheline = id->l3_cacheline = id->l4_cacheline = -1;
|
||||
id->l1_assoc = id->l1_data_assoc = id->l1_instruction_assoc = id->l2_assoc = id->l3_assoc = id->l4_assoc = -1;
|
||||
id->l1_cacheline = id->l1_data_cacheline = id->l1_instruction_cacheline = id->l2_cacheline = id->l3_cacheline = id->l4_cacheline = -1;
|
||||
id->sse_size = -1;
|
||||
}
|
||||
|
||||
|
@ -548,6 +548,10 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct
|
|||
default:
|
||||
break;
|
||||
}
|
||||
/* Backward compatibility */
|
||||
/* - Deprecated since v0.5.0 */
|
||||
data->l1_assoc = data->l1_data_assoc;
|
||||
data->l1_cacheline = data->l1_data_cacheline;
|
||||
return set_error(r);
|
||||
}
|
||||
|
||||
|
|
|
@ -310,9 +310,17 @@ struct cpu_id_t {
|
|||
/** L4 cache size in KB. Zero on most systems */
|
||||
int32_t l4_cache;
|
||||
|
||||
/** Cache associativity for the L1 data cache. -1 if undetermined */
|
||||
/** Cache associativity for the L1 data cache. -1 if undetermined
|
||||
* @deprecated replaced by \ref cpu_id_t::l1_data_assoc
|
||||
*/
|
||||
int32_t l1_assoc;
|
||||
|
||||
/** Cache associativity for the L1 data cache. -1 if undetermined */
|
||||
int32_t l1_data_assoc;
|
||||
|
||||
/** Cache associativity for the L1 intruction cache. -1 if undetermined */
|
||||
int32_t l1_instruction_assoc;
|
||||
|
||||
/** Cache associativity for the L2 cache. -1 if undetermined */
|
||||
int32_t l2_assoc;
|
||||
|
||||
|
@ -322,9 +330,17 @@ struct cpu_id_t {
|
|||
/** Cache associativity for the L4 cache. -1 if undetermined */
|
||||
int32_t l4_assoc;
|
||||
|
||||
/** Cache-line size for L1 data cache. -1 if undetermined */
|
||||
/** Cache-line size for L1 data cache. -1 if undetermined
|
||||
* @deprecated replaced by \ref cpu_id_t::l1_data_cacheline
|
||||
*/
|
||||
int32_t l1_cacheline;
|
||||
|
||||
/** Cache-line size for L1 data cache. -1 if undetermined */
|
||||
int32_t l1_data_cacheline;
|
||||
|
||||
/** Cache-line size for L1 intruction cache. -1 if undetermined */
|
||||
int32_t l1_instruction_cacheline;
|
||||
|
||||
/** Cache-line size for L2 cache. -1 if undetermined */
|
||||
int32_t l2_cacheline;
|
||||
|
||||
|
|
|
@ -375,10 +375,15 @@ static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* d
|
|||
unsigned n = raw->ext_cpuid[0][EAX];
|
||||
|
||||
if (n >= 0x80000005) {
|
||||
data->l1_data_cache = (raw->ext_cpuid[5][ECX] >> 24) & 0xff;
|
||||
data->l1_assoc = (raw->ext_cpuid[5][ECX] >> 16) & 0xff;
|
||||
data->l1_cacheline = (raw->ext_cpuid[5][ECX]) & 0xff;
|
||||
data->l1_instruction_cache = (raw->ext_cpuid[5][EDX] >> 24) & 0xff;
|
||||
/* L1 Data Cache */
|
||||
data->l1_data_cache = EXTRACTS_BITS(raw->ext_cpuid[5][ECX], 31, 24); // L1DcSize
|
||||
data->l1_data_assoc = EXTRACTS_BITS(raw->ext_cpuid[5][ECX], 23, 16); // L1DcAssoc
|
||||
data->l1_data_cacheline = EXTRACTS_BITS(raw->ext_cpuid[5][ECX], 7, 0); // L1DcLineSize
|
||||
|
||||
/* L1 Instruction Cache */
|
||||
data->l1_instruction_cache = EXTRACTS_BITS(raw->ext_cpuid[5][EDX], 31, 24); // L1IcSize
|
||||
data->l1_instruction_assoc = EXTRACTS_BITS(raw->ext_cpuid[5][EDX], 23, 16); // L1IcAssoc
|
||||
data->l1_instruction_cacheline = EXTRACTS_BITS(raw->ext_cpuid[5][EDX], 7, 0); // L1IcLineSize
|
||||
}
|
||||
if (n >= 0x80000006) {
|
||||
data->l2_cache = (raw->ext_cpuid[6][ECX] >> 16) & 0xffff;
|
||||
|
@ -398,7 +403,7 @@ static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* d
|
|||
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 */
|
||||
Note: we do not read CPUID_Fn80000001_ECX[22] (AKA TopologyExtensions) to allow backward compatibility 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 {
|
||||
|
|
|
@ -463,11 +463,13 @@ static void check_case(uint8_t on, cache_type_t cache, int size, int assoc, int
|
|||
switch (cache) {
|
||||
case L1I:
|
||||
data->l1_instruction_cache = size;
|
||||
data->l1_instruction_assoc = assoc;
|
||||
data->l1_instruction_cacheline = linesize;
|
||||
break;
|
||||
case L1D:
|
||||
data->l1_data_cache = size;
|
||||
data->l1_assoc = assoc;
|
||||
data->l1_cacheline = linesize;
|
||||
data->l1_data_assoc = assoc;
|
||||
data->l1_data_cacheline = linesize;
|
||||
break;
|
||||
case L2:
|
||||
data->l2_cache = size;
|
||||
|
|
Loading…
Reference in a new issue