Commit 3279081d authored by Thomas Gleixner's avatar Thomas Gleixner

x86/cpu: Use common topology code for HYGON

Switch it over to use the consolidated topology evaluation and remove the
temporary safe guards which are not longer needed.

No functional change intended.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarJuergen Gross <jgross@suse.com>
Tested-by: default avatarSohil Mehta <sohil.mehta@intel.com>
Tested-by: default avatarMichael Kelley <mhklinux@outlook.com>
Tested-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarWang Wendy <wendy.wang@intel.com>
Tested-by: default avatarK Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20240212153625.207750409@linutronix.de


parent c749ce39
...@@ -1780,11 +1780,6 @@ static void identify_cpu(struct cpuinfo_x86 *c) ...@@ -1780,11 +1780,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
/* Clear/Set all flags overridden by options, after probe */ /* Clear/Set all flags overridden by options, after probe */
apply_forced_caps(c); apply_forced_caps(c);
#ifdef CONFIG_X86_64
if (!topo_is_converted(c))
c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
#endif
/* /*
* Set default APIC and TSC_DEADLINE MSR fencing flag. AMD and * Set default APIC and TSC_DEADLINE MSR fencing flag. AMD and
* Hygon will clear it in ->c_init() below. * Hygon will clear it in ->c_init() below.
......
...@@ -76,7 +76,6 @@ extern void init_intel_cacheinfo(struct cpuinfo_x86 *c); ...@@ -76,7 +76,6 @@ extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
extern void init_amd_cacheinfo(struct cpuinfo_x86 *c); extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c); extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
extern int detect_extended_topology(struct cpuinfo_x86 *c);
extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id); void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id);
......
...@@ -18,14 +18,6 @@ ...@@ -18,14 +18,6 @@
#include "cpu.h" #include "cpu.h"
#define APICID_SOCKET_ID_BIT 6
/*
* nodes_per_socket: Stores the number of nodes per socket.
* Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
*/
static u32 nodes_per_socket = 1;
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
/* /*
* To workaround broken NUMA config. Read the comment in * To workaround broken NUMA config. Read the comment in
...@@ -49,80 +41,6 @@ static int nearby_node(int apicid) ...@@ -49,80 +41,6 @@ static int nearby_node(int apicid)
} }
#endif #endif
static void hygon_get_topology_early(struct cpuinfo_x86 *c)
{
if (cpu_has(c, X86_FEATURE_TOPOEXT))
smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
}
/*
* Fixup core topology information for
* (1) Hygon multi-node processors
* Assumption: Number of cores in each internal node is the same.
* (2) Hygon processors supporting compute units
*/
static void hygon_get_topology(struct cpuinfo_x86 *c)
{
/* get information required for multi-node processors */
if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
int err;
u32 eax, ebx, ecx, edx;
cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
c->topo.die_id = ecx & 0xff;
c->topo.core_id = ebx & 0xff;
if (smp_num_siblings > 1)
c->x86_max_cores /= smp_num_siblings;
/*
* In case leaf B is available, use it to derive
* topology information.
*/
err = detect_extended_topology(c);
if (!err)
c->x86_coreid_bits = get_count_order(c->x86_max_cores);
/*
* Socket ID is ApicId[6] for the processors with model <= 0x3
* when running on host.
*/
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && c->x86_model <= 0x3)
c->topo.pkg_id = c->topo.apicid >> APICID_SOCKET_ID_BIT;
cacheinfo_hygon_init_llc_id(c);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
u64 value;
rdmsrl(MSR_FAM10H_NODE_ID, value);
c->topo.die_id = value & 7;
c->topo.llc_id = c->topo.die_id;
} else
return;
if (nodes_per_socket > 1)
set_cpu_cap(c, X86_FEATURE_AMD_DCM);
}
/*
* On Hygon setup the lower bits of the APIC id distinguish the cores.
* Assumes number of cores is a power of two.
*/
static void hygon_detect_cmp(struct cpuinfo_x86 *c)
{
unsigned int bits;
bits = c->x86_coreid_bits;
/* Low order bits define the core id (index of core in socket) */
c->topo.core_id = c->topo.initial_apicid & ((1 << bits)-1);
/* Convert the initial APIC ID into the socket ID */
c->topo.pkg_id = c->topo.initial_apicid >> bits;
/* Use package ID also for last level cache */
c->topo.llc_id = c->topo.die_id = c->topo.pkg_id;
}
static void srat_detect_node(struct cpuinfo_x86 *c) static void srat_detect_node(struct cpuinfo_x86 *c)
{ {
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
...@@ -173,32 +91,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c) ...@@ -173,32 +91,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
#endif #endif
} }
static void early_init_hygon_mc(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_SMP
unsigned int bits, ecx;
/* Multi core CPU? */
if (c->extended_cpuid_level < 0x80000008)
return;
ecx = cpuid_ecx(0x80000008);
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++;
}
c->x86_coreid_bits = bits;
#endif
}
static void bsp_init_hygon(struct cpuinfo_x86 *c) static void bsp_init_hygon(struct cpuinfo_x86 *c)
{ {
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
...@@ -212,18 +104,6 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c) ...@@ -212,18 +104,6 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_MWAITX)) if (cpu_has(c, X86_FEATURE_MWAITX))
use_mwaitx_delay(); use_mwaitx_delay();
if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
u32 ecx;
ecx = cpuid_ecx(0x8000001e);
__max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1;
} else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
u64 value;
rdmsrl(MSR_FAM10H_NODE_ID, value);
__max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1;
}
if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
!boot_cpu_has(X86_FEATURE_VIRT_SSBD)) { !boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
/* /*
...@@ -242,8 +122,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c) ...@@ -242,8 +122,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
{ {
u32 dummy; u32 dummy;
early_init_hygon_mc(c);
set_cpu_cap(c, X86_FEATURE_K8); set_cpu_cap(c, X86_FEATURE_K8);
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
...@@ -284,8 +162,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c) ...@@ -284,8 +162,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
* we can set it unconditionally. * we can set it unconditionally.
*/ */
set_cpu_cap(c, X86_FEATURE_VMMCALL); set_cpu_cap(c, X86_FEATURE_VMMCALL);
hygon_get_topology_early(c);
} }
static void init_hygon(struct cpuinfo_x86 *c) static void init_hygon(struct cpuinfo_x86 *c)
...@@ -302,9 +178,6 @@ static void init_hygon(struct cpuinfo_x86 *c) ...@@ -302,9 +178,6 @@ static void init_hygon(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_REP_GOOD); set_cpu_cap(c, X86_FEATURE_REP_GOOD);
/* get apicid instead of initial apic id from cpuid */
c->topo.apicid = read_apic_id();
/* /*
* XXX someone from Hygon needs to confirm this DTRT * XXX someone from Hygon needs to confirm this DTRT
* *
...@@ -316,8 +189,6 @@ static void init_hygon(struct cpuinfo_x86 *c) ...@@ -316,8 +189,6 @@ static void init_hygon(struct cpuinfo_x86 *c)
cpu_detect_cache_sizes(c); cpu_detect_cache_sizes(c);
hygon_detect_cmp(c);
hygon_get_topology(c);
srat_detect_node(c); srat_detect_node(c);
init_hygon_cacheinfo(c); init_hygon_cacheinfo(c);
......
...@@ -15,7 +15,6 @@ struct topo_scan { ...@@ -15,7 +15,6 @@ struct topo_scan {
u16 amd_node_id; u16 amd_node_id;
}; };
bool topo_is_converted(struct cpuinfo_x86 *c);
void cpu_init_topology(struct cpuinfo_x86 *c); void cpu_init_topology(struct cpuinfo_x86 *c);
void cpu_parse_topology(struct cpuinfo_x86 *c); void cpu_parse_topology(struct cpuinfo_x86 *c);
void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom, void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
......
...@@ -68,18 +68,6 @@ static void parse_legacy(struct topo_scan *tscan) ...@@ -68,18 +68,6 @@ static void parse_legacy(struct topo_scan *tscan)
topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores); topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
} }
bool topo_is_converted(struct cpuinfo_x86 *c)
{
/* Temporary until everything is converted over. */
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_HYGON:
return false;
default:
/* Let all UP systems use the below */
return true;
}
}
static bool fake_topology(struct topo_scan *tscan) static bool fake_topology(struct topo_scan *tscan)
{ {
/* /*
...@@ -144,6 +132,10 @@ static void parse_topology(struct topo_scan *tscan, bool early) ...@@ -144,6 +132,10 @@ static void parse_topology(struct topo_scan *tscan, bool early)
if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan)) if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
parse_legacy(tscan); parse_legacy(tscan);
break; break;
case X86_VENDOR_HYGON:
if (IS_ENABLED(CONFIG_CPU_SUP_HYGON))
cpu_parse_topology_amd(tscan);
break;
} }
} }
...@@ -187,9 +179,6 @@ void cpu_parse_topology(struct cpuinfo_x86 *c) ...@@ -187,9 +179,6 @@ void cpu_parse_topology(struct cpuinfo_x86 *c)
parse_topology(&tscan, false); parse_topology(&tscan, false);
if (!topo_is_converted(c))
return;
for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++) { for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++) {
if (tscan.dom_shifts[dom] == x86_topo_system.dom_shifts[dom]) if (tscan.dom_shifts[dom] == x86_topo_system.dom_shifts[dom])
continue; continue;
...@@ -218,9 +207,6 @@ void __init cpu_init_topology(struct cpuinfo_x86 *c) ...@@ -218,9 +207,6 @@ void __init cpu_init_topology(struct cpuinfo_x86 *c)
parse_topology(&tscan, true); parse_topology(&tscan, true);
if (!topo_is_converted(c))
return;
/* Copy the shift values and calculate the unit sizes. */ /* Copy the shift values and calculate the unit sizes. */
memcpy(x86_topo_system.dom_shifts, tscan.dom_shifts, sizeof(x86_topo_system.dom_shifts)); memcpy(x86_topo_system.dom_shifts, tscan.dom_shifts, sizeof(x86_topo_system.dom_shifts));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment