|
@@ -538,7 +538,11 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
|
|
|
unsigned edx;
|
|
|
|
|
|
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
|
|
|
- amd_cpuid4(index, &eax, &ebx, &ecx);
|
|
|
+ if (cpu_has_topoext)
|
|
|
+ cpuid_count(0x8000001d, index, &eax.full,
|
|
|
+ &ebx.full, &ecx.full, &edx);
|
|
|
+ else
|
|
|
+ amd_cpuid4(index, &eax, &ebx, &ecx);
|
|
|
amd_init_l3_cache(this_leaf, index);
|
|
|
} else {
|
|
|
cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
|
|
@@ -557,21 +561,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 */
|
|
@@ -588,7 +610,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++;
|
|
|
}
|
|
|
|
|
@@ -728,37 +750,50 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
|
|
|
static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
|
|
|
{
|
|
|
struct _cpuid4_info *this_leaf;
|
|
|
- int ret, i, sibling;
|
|
|
- struct cpuinfo_x86 *c = &cpu_data(cpu);
|
|
|
+ int i, sibling;
|
|
|
|
|
|
- ret = 0;
|
|
|
- if (index == 3) {
|
|
|
- ret = 1;
|
|
|
- for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
|
|
|
+ if (cpu_has_topoext) {
|
|
|
+ unsigned int apicid, nshared, first, last;
|
|
|
+
|
|
|
+ if (!per_cpu(ici_cpuid4_info, cpu))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ this_leaf = CPUID4_INFO_IDX(cpu, index);
|
|
|
+ nshared = this_leaf->base.eax.split.num_threads_sharing + 1;
|
|
|
+ apicid = cpu_data(cpu).apicid;
|
|
|
+ first = apicid - (apicid % nshared);
|
|
|
+ last = first + nshared - 1;
|
|
|
+
|
|
|
+ for_each_online_cpu(i) {
|
|
|
+ apicid = cpu_data(i).apicid;
|
|
|
+ if ((apicid < first) || (apicid > last))
|
|
|
+ continue;
|
|
|
if (!per_cpu(ici_cpuid4_info, i))
|
|
|
continue;
|
|
|
this_leaf = CPUID4_INFO_IDX(i, index);
|
|
|
- for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) {
|
|
|
- if (!cpu_online(sibling))
|
|
|
+
|
|
|
+ for_each_online_cpu(sibling) {
|
|
|
+ apicid = cpu_data(sibling).apicid;
|
|
|
+ if ((apicid < first) || (apicid > last))
|
|
|
continue;
|
|
|
set_bit(sibling, this_leaf->shared_cpu_map);
|
|
|
}
|
|
|
}
|
|
|
- } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
|
|
|
- ret = 1;
|
|
|
- for_each_cpu(i, cpu_sibling_mask(cpu)) {
|
|
|
+ } else if (index == 3) {
|
|
|
+ for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
|
|
|
if (!per_cpu(ici_cpuid4_info, i))
|
|
|
continue;
|
|
|
this_leaf = CPUID4_INFO_IDX(i, index);
|
|
|
- for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
|
|
|
+ for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) {
|
|
|
if (!cpu_online(sibling))
|
|
|
continue;
|
|
|
set_bit(sibling, this_leaf->shared_cpu_map);
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ } else
|
|
|
+ return 0;
|
|
|
|
|
|
- return ret;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
|