From d4bd76807e6d4dc86020e7ecd56467ce0fc55c67 Mon Sep 17 00:00:00 2001 From: Stuart Henderson Date: Wed, 20 Jun 2018 19:30:35 +0000 Subject: On newer AMD parts, use CoreId (EBX) and NodeId (ECX) from cpuid 0x8000001e to detect smt cores. As there's no "smt id" on these like there is on Intel parts, check against other already-id'd cpus to detect which are additional smt threads on a core. jmatthew noticed some unusual (non-contiguous) numbering on an single socket EPYC 7551p but there's no indication that the actual ID numbers need to be sequential. "As long as we treat ci_core_id as just a number, that shouldn't be an issue" and OK kettenis@ ref: 54945 rev 1.14 - PPR for AMD Family 17h Models 00h-0Fh --- sys/arch/amd64/amd64/identcpu.c | 50 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'sys/arch/amd64') diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index da6a3ca68d5..bbe1c118ac6 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.96 2018/06/07 04:07:28 guenther Exp $ */ +/* $OpenBSD: identcpu.c,v 1.97 2018/06/20 19:30:34 sthen Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -792,18 +792,36 @@ cpu_topology(struct cpu_info *ci) if (ci->ci_pnfeatset < 0x80000008) goto no_topology; - CPUID(0x80000008, eax, ebx, ecx, edx); - core_bits = (ecx >> 12) & 0xf; - if (core_bits == 0) - goto no_topology; - /* So coreidsize 2 gives 3, 3 gives 7... */ - core_mask = (1 << core_bits) - 1; - /* Core id is the least significant considering mask */ - ci->ci_core_id = apicid & core_mask; - /* Pkg id is the upper remaining bits */ - ci->ci_pkg_id = apicid & ~core_mask; - ci->ci_pkg_id >>= core_bits; + if (ci->ci_pnfeatset >= 0x8000001e) { + struct cpu_info *ci_other; + CPU_INFO_ITERATOR cii; + + CPUID(0x8000001e, eax, ebx, ecx, edx); + ci->ci_core_id = ebx & 0xff; + ci->ci_pkg_id = ecx & 0xff; + ci->ci_smt_id = 0; + CPU_INFO_FOREACH(cii, ci_other) { + if (ci != ci_other && + ci_other->ci_core_id == ci->ci_core_id) + ci->ci_smt_id++; + } + } else { + CPUID(0x80000008, eax, ebx, ecx, edx); + core_bits = (ecx >> 12) & 0xf; + if (core_bits == 0) + goto no_topology; + /* So coreidsize 2 gives 3, 3 gives 7... */ + core_mask = (1 << core_bits) - 1; + /* Core id is the least significant considering mask */ + ci->ci_core_id = apicid & core_mask; + /* Pkg id is the upper remaining bits */ + ci->ci_pkg_id = apicid & ~core_mask; + ci->ci_pkg_id >>= core_bits; + } } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { + struct cpu_info *ci_other; + CPU_INFO_ITERATOR cii; + /* We only support leaf 1/4 detection */ if (cpuid_level < 4) goto no_topology; @@ -824,9 +842,15 @@ cpu_topology(struct cpu_info *ci) pkg_bits = core_bits + smt_bits; pkg_mask = -1 << core_bits; - ci->ci_smt_id = apicid & smt_mask; + // ci->ci_smt_id = apicid & smt_mask; ci->ci_core_id = (apicid & core_mask) >> smt_bits; ci->ci_pkg_id = (apicid & pkg_mask) >> pkg_bits; + ci->ci_smt_id = 0; + CPU_INFO_FOREACH(cii, ci_other) { + if (ci != ci_other && + ci_other->ci_core_id == ci->ci_core_id) + ci->ci_smt_id++; + } } else goto no_topology; #ifdef DEBUG -- cgit v1.2.3