i386/x86-64: Use new official CPUID to get APICID/core split on AMD platforms
PATCH 4/82 i386/x86-64: Use new official CPUID to get APICID/core split on AMD platforms
Previously the apicid<->coreid split was computed based on the max number of cores. Now use a new CPUID AMD defined for that. On most systems right now it should be 0 and the old method will be used.
Signed-off-by Andi Kleen <[email protected]>
--- arch/i386/kernel/cpu/amd.c | 14 ++++++++------ arch/x86_64/kernel/setup.c | 20 +++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-)
arch/x86_64/kernel/setup.c +13 -7
@@ -968,10 +968,18 @@ static void __init amd_detect_cmp(structint node =0 ;unsigned apicid =hard_smp_processor_id ();#endif +unsigned ecx =cpuid_ecx (0x80000008 ); - bits =0 ; -while ((1 << bits) < c->x86_max_cores) - bits++; + c->x86_max_cores = (ecx &0xff ) +1 ; + +/* CPU telling us the core id bits shift? */ + bits = (ecx >>12 ) &0xF ; + +/* Otherwise recompute */ +if (bits ==0 ) { +while ((1 << bits) < c->x86_max_cores) + bits++; + }/* Low order bits define the core id (index of core in socket) */ cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1 );
@@ -1059,11 +1067,9 @@ static int __init init_amd(struct cpuinfif (c->x86_power & (1 <<8 ))set_bit (X86_FEATURE_CONSTANT_TSC , &c->x86_capability); -if (c->extended_cpuid_level >=0x80000008 ) { - c->x86_max_cores = (cpuid_ecx (0x80000008 ) &0xff ) +1 ; - +/* Multi core CPU? */ +if (c->extended_cpuid_level >=0x80000008 )amd_detect_cmp (c); - }return r; }
arch/i386/kernel/cpu/amd.c +8 -6
@@ -224,15 +224,17 @@ static void __init init_amd(struct cpuin#ifdef CONFIG_X86_HT /* -* On a AMD dual core setup the lower bits of the APIC id -* distingush the cores. Assumes number of cores is a power -* of two. +* On a AMD multi core setup the lower bits of the APIC id +* distingush the cores. */ if (c->x86_max_cores >1 ) {int cpu =smp_processor_id (); -unsigned bits =0 ; -while ((1 << bits) < c->x86_max_cores) - bits++; +unsigned bits = (cpuid_ecx (0x80000008 ) >>12 ) &0xf ; + +if (bits ==0 ) { +while ((1 << bits) < c->x86_max_cores) + bits++; + } cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 <<bits)-1 ); phys_proc_id[cpu] >>= bits; printk(KERN_INFO "CPU %d(%d) -> Core %d\n",