Skip to content

Commit

Permalink
x86, cacheinfo: Determine number of cache leafs using CPUID 0x8000001…
Browse files Browse the repository at this point in the history
…d on AMD

CPUID 0x8000001d works quite similar to Intels' CPUID function 4.
Use it to determine number of cache leafs.

Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
Link: http://lkml.kernel.org/r/20121019085933.GE26718@alberich
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
  • Loading branch information
Andreas Herrmann authored and H. Peter Anvin committed Nov 13, 2012
1 parent 193f3fc commit 04a1541
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ extern void print_cpu_info(struct cpuinfo_x86 *);
void print_cpu_msr(struct cpuinfo_x86 *);
extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
extern unsigned short num_cache_leaves;
extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);

extern void detect_extended_topology(struct cpuinfo_x86 *c);
extern void detect_ht(struct cpuinfo_x86 *c);
Expand Down
7 changes: 1 addition & 6 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,12 +643,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
detect_ht(c);
#endif

if (c->extended_cpuid_level >= 0x80000006) {
if (cpuid_edx(0x80000006) & 0xf000)
num_cache_leaves = 4;
else
num_cache_leaves = 3;
}
init_amd_cacheinfo(c);

if (c->x86 >= 0xf)
set_cpu_cap(c, X86_FEATURE_K8);
Expand Down
28 changes: 23 additions & 5 deletions arch/x86/kernel/cpu/intel_cacheinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,21 +557,39 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
return 0;
}

static int __cpuinit find_num_cache_leaves(void)
static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c)
{
unsigned int eax, ebx, ecx, edx;
unsigned int eax, ebx, ecx, edx, op;
union _cpuid4_leaf_eax cache_eax;
int i = -1;

if (c->x86_vendor == X86_VENDOR_AMD)
op = 0x8000001d;
else
op = 4;

do {
++i;
/* Do cpuid(4) loop to find out num_cache_leaves */
cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
/* Do cpuid(op) loop to find out num_cache_leaves */
cpuid_count(op, i, &eax, &ebx, &ecx, &edx);
cache_eax.full = eax;
} while (cache_eax.split.type != CACHE_TYPE_NULL);
return i;
}

void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c)
{

if (cpu_has_topoext) {
num_cache_leaves = find_num_cache_leaves(c);
} else if (c->extended_cpuid_level >= 0x80000006) {
if (cpuid_edx(0x80000006) & 0xf000)
num_cache_leaves = 4;
else
num_cache_leaves = 3;
}
}

unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
{
/* Cache sizes */
Expand All @@ -588,7 +606,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)

if (is_initialized == 0) {
/* Init num_cache_leaves from boot CPU */
num_cache_leaves = find_num_cache_leaves();
num_cache_leaves = find_num_cache_leaves(c);
is_initialized++;
}

Expand Down

0 comments on commit 04a1541

Please sign in to comment.