diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2013-05-23 09:14:57 -0400 |
---|---|---|
committer | Søren Sandmann <ssp@redhat.com> | 2013-10-06 02:52:31 -0400 |
commit | 9b3e91abfe918ec5ecf1c0c24831f0cd9aeadc22 (patch) | |
tree | 4cf7737fd3e954d9b7b3c90560f7657fb531ce64 | |
parent | d1a6d2bb69b6dc549b1e3a4a54d4713263a3612e (diff) |
When cpuid.2 reports a cache descriptor of 0xff, that means cpuid.2
doesn't contain any information about caches and that instead you are
supposed to find this information in cpuid.4.
This patch adds support for decoding that information.
-rw-r--r-- | Intel/cachesize.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Intel/cachesize.c b/Intel/cachesize.c index cfdec55..d2ede40 100644 --- a/Intel/cachesize.c +++ b/Intel/cachesize.c @@ -178,6 +178,7 @@ static struct _cache_table prefetch_table[] = }; static unsigned char found_unknown=0; +static unsigned char found_general=0; static unsigned char unknown_array[256]; /* Decode Intel TLB and cache info descriptors */ @@ -193,6 +194,11 @@ static void decode_Intel_cache(int des, struct cpudata *cpu, int output, if (des == 0x40) return; + if (des == 0xff) { + found_general = 1; + return; + } + //TODO: Add description to link-list in cpu-> while ((table[k].descriptor != 0) && (found == 0)) { @@ -272,6 +278,51 @@ static void clean_unknowns(struct _cache_table *table) } } +static const char *cache_types[32] = +{ + NULL, + "Data Cache", + "Instruction Cache", + "Unified Cache", +}; + +static void decode_general_cache(struct cpudata *cpu, int output) +{ + unsigned int i; + unsigned int a, b, c, d; + const char *type; + unsigned int level; + unsigned int associativity; + unsigned int partitions; + unsigned int line_size; + unsigned int sets; + unsigned int size; + + if (cpu->cpuid_level < 4) + return; + + i = 0; + for (;;) { + cpuid4(cpu->number, i++, &a, &b, &c, &d); + if ((a & 0x1f) == 0) + break; + + type = cache_types[a & 0x1f]; + if (!type) + type = "Unknown Cache Type"; + level = (a >> 5) & 0x7; + associativity = ((b >> 22) & 0x3ff) + 1; + partitions = ((b >> 12) & 0x3ff) + 1; + line_size = ((b >> 0) & 0xfff) + 1; + sets = c + 1; + + size = (associativity * partitions * line_size * sets) / 1024; + + if (output) + printf(" L%d %s: %dKB, %d-way associative, %d byte line size\n", + level, type, size, associativity, line_size); + } +} void decode_Intel_caches(struct cpudata *cpu, int output) { @@ -299,6 +350,14 @@ void decode_Intel_caches(struct cpudata *cpu, int output) } decode_cache(cpu, L3_cache_table, output); + /* The cache descriptor 0xff means the CPU doesn't provide any + * cache information in cpuid.2. It is instead provided in + * cpuid.4. + */ + if (found_general) { + decode_general_cache (cpu, output); + found_general = 0; + }; if (output) printf("TLB info\n"); decode_cache(cpu, ITLB_cache_table, output); |