Index: arch/aarch64/aarch64/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/cpu.c,v retrieving revision 1.33 diff -p -u -r1.33 cpu.c --- arch/aarch64/aarch64/cpu.c 12 Jan 2020 09:29:18 -0000 1.33 +++ arch/aarch64/aarch64/cpu.c 12 Jan 2020 12:41:10 -0000 @@ -48,6 +48,7 @@ __KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.33 #include #include +#include #ifdef FDT #include #endif @@ -65,7 +66,6 @@ static void cpu_identify1(device_t self, static void cpu_identify2(device_t self, struct cpu_info *); static void cpu_setup_id(struct cpu_info *); static void cpu_setup_sysctl(device_t, struct cpu_info *); -static void cpu_do_topology(struct cpu_info *); #ifdef MULTIPROCESSOR uint64_t cpu_mpidr[MAXCPUS]; @@ -145,7 +145,7 @@ cpu_attach(device_t dv, cpuid_t id) ci->ci_dev = dv; dv->dv_private = ci; - cpu_do_topology(ci); + arm_cpu_do_topology(ci); cpu_identify(ci->ci_dev, ci); #ifdef MULTIPROCESSOR @@ -498,43 +498,6 @@ cpu_setup_sysctl(device_t dv, struct cpu CTL_CREATE, CTL_EOL); } -static void -cpu_do_topology(struct cpu_info *newci) -{ - struct cpu_info *ci; - CPU_INFO_ITERATOR cii; - prop_dictionary_t dict; - uint32_t capacity_dmips_mhz; - static uint32_t best_cap = 0; - - dict = device_properties(newci->ci_dev); - if (prop_dictionary_get_uint32(dict, "capacity_dmips_mhz", - &capacity_dmips_mhz)) { - newci->ci_capacity_dmips_mhz = capacity_dmips_mhz; - } else { - newci->ci_capacity_dmips_mhz = 0; - } - - if (newci->ci_capacity_dmips_mhz > best_cap) - best_cap = newci->ci_capacity_dmips_mhz; - - /* - * CPU_INFO_FOREACH() doesn't work for this CPU until mi_cpu_attach() - * is called and ncpu is bumped, so call it directly here. - */ - aarch64_set_topology(newci, newci->ci_id.ac_mpidr, - newci->ci_capacity_dmips_mhz < best_cap); - - /* - * Using saved largest capacity, refresh previous topology info. - * It's supposed to be OK to re-set topology. - */ - for (CPU_INFO_FOREACH(cii, ci)) { - aarch64_set_topology(ci, ci->ci_id.ac_mpidr, - ci->ci_capacity_dmips_mhz < best_cap); - } -} - #ifdef MULTIPROCESSOR void cpu_boot_secondary_processors(void) Index: arch/aarch64/aarch64/cpufunc.c =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/cpufunc.c,v retrieving revision 1.14 diff -p -u -r1.14 cpufunc.c --- arch/aarch64/aarch64/cpufunc.c 12 Jan 2020 09:29:18 -0000 1.14 +++ arch/aarch64/aarch64/cpufunc.c 12 Jan 2020 12:41:10 -0000 @@ -89,27 +89,6 @@ extract_cacheunit(int level, bool insn, } void -aarch64_set_topology(struct cpu_info * const ci, uint64_t mpidr, bool slow) -{ - - if (mpidr & MPIDR_MT) { - cpu_topology_set(ci, - __SHIFTOUT(mpidr, MPIDR_AFF2), - __SHIFTOUT(mpidr, MPIDR_AFF1), - __SHIFTOUT(mpidr, MPIDR_AFF0), - 0, - slow); - } else { - cpu_topology_set(ci, - __SHIFTOUT(mpidr, MPIDR_AFF1), - __SHIFTOUT(mpidr, MPIDR_AFF0), - 0, - 0, - slow); - } -} - -void aarch64_getcacheinfo(int unit) { struct cpu_info * const ci = curcpu(); Index: arch/aarch64/aarch64/locore.S =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/locore.S,v retrieving revision 1.51 diff -p -u -r1.51 locore.S --- arch/aarch64/aarch64/locore.S 12 Jan 2020 09:29:18 -0000 1.51 +++ arch/aarch64/aarch64/locore.S 12 Jan 2020 12:41:10 -0000 @@ -188,7 +188,7 @@ vstart: mrs x0, tpidr_el1 /* curcpu */ mrs x1, mpidr_el1 mov x2, #0 - bl aarch64_set_topology + bl arm_cpu_topology_set mov x0, xzr bl aarch64_getcacheinfo Index: arch/aarch64/conf/files.aarch64 =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/conf/files.aarch64,v retrieving revision 1.16 diff -p -u -r1.16 files.aarch64 --- arch/aarch64/conf/files.aarch64 28 Dec 2019 17:19:43 -0000 1.16 +++ arch/aarch64/conf/files.aarch64 12 Jan 2020 12:41:10 -0000 @@ -41,6 +41,7 @@ defparam opt_console.h CONADDR file arch/aarch64/aarch64/fpu.c file arch/arm/arm/arm_generic_dma.c +file arch/arm/arm/arm_cpu_topology.c file arch/arm/arm32/bus_dma.c device psci Index: arch/aarch64/include/cpu.h =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/include/cpu.h,v retrieving revision 1.18 diff -p -u -r1.18 cpu.h --- arch/aarch64/include/cpu.h 12 Jan 2020 09:29:18 -0000 1.18 +++ arch/aarch64/include/cpu.h 12 Jan 2020 12:41:10 -0000 @@ -104,6 +104,7 @@ struct cpu_info { uint64_t ci_acpiid; /* ACPI Processor Unique ID */ struct aarch64_sysctl_cpu_id ci_id; +#define arm_cpu_mpidr(ci) ((ci)->ci_id.ac_mpidr) struct aarch64_cache_info *ci_cacheinfo; struct aarch64_cpufuncs ci_cpufuncs; Index: arch/aarch64/include/cpufunc.h =================================================================== RCS file: /cvsroot/src/sys/arch/aarch64/include/cpufunc.h,v retrieving revision 1.10 diff -p -u -r1.10 cpufunc.h --- arch/aarch64/include/cpufunc.h 12 Jan 2020 09:29:18 -0000 1.10 +++ arch/aarch64/include/cpufunc.h 12 Jan 2020 12:41:10 -0000 @@ -69,7 +69,6 @@ extern u_int aarch64_cache_prefer_mask; extern u_int cputype; /* compat arm */ int set_cpufuncs(void); -void aarch64_set_topology(struct cpu_info *, uint64_t, bool); void aarch64_getcacheinfo(int); void aarch64_printcacheinfo(device_t); Index: arch/arm/arm/arm_cpu_topology.c =================================================================== RCS file: arch/arm/arm/arm_cpu_topology.c diff -N arch/arm/arm/arm_cpu_topology.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/arm/arm/arm_cpu_topology.c 12 Jan 2020 12:41:10 -0000 @@ -0,0 +1,101 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2020 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_multiprocessor.h" + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +void +arm_cpu_topology_set(struct cpu_info * const ci, uint64_t mpidr, bool slow) +{ + uint pkgid, coreid, smtid, numaid = 0; + + if (mpidr & MPIDR_MT) { + pkgid = __SHIFTOUT(mpidr, MPIDR_AFF2); + coreid = __SHIFTOUT(mpidr, MPIDR_AFF1); + smtid = __SHIFTOUT(mpidr, MPIDR_AFF0); + } else { + pkgid = __SHIFTOUT(mpidr, MPIDR_AFF1); + coreid = __SHIFTOUT(mpidr, MPIDR_AFF0); + smtid = 0; + } + cpu_topology_set(ci, pkgid, coreid, smtid, numaid, slow); +} + +void +arm_cpu_do_topology(struct cpu_info *const newci) +{ +#ifdef MULTIPROCESSOR + struct cpu_info *ci; + CPU_INFO_ITERATOR cii; +#endif /* MULTIPROCESSOR */ + prop_dictionary_t dict; + uint32_t capacity_dmips_mhz = 0; + static uint32_t best_cap = 0; + + dict = device_properties(newci->ci_dev); + if (prop_dictionary_get_uint32(dict, "capacity_dmips_mhz", + &capacity_dmips_mhz)) + newci->ci_capacity_dmips_mhz = capacity_dmips_mhz; + + if (newci->ci_capacity_dmips_mhz > best_cap) + best_cap = newci->ci_capacity_dmips_mhz; + + /* + * CPU_INFO_FOREACH() doesn't work for this CPU until mi_cpu_attach() + * is called and ncpu is bumped, so call it directly here. This also + * handles the not-MP case. + */ + arm_cpu_topology_set(newci, arm_cpu_mpidr(newci), + newci->ci_capacity_dmips_mhz < best_cap); + +#ifdef MULTIPROCESSOR + /* + * Using saved largest capacity, refresh previous topology info. + * It's supposed to be OK to re-set topology. + */ + for (CPU_INFO_FOREACH(cii, ci)) { + KASSERT(ci != newci); + arm_cpu_topology_set(ci, arm_cpu_mpidr(ci), + ci->ci_capacity_dmips_mhz < best_cap); + } +#endif /* MULTIPROCESSOR */ +} Index: arch/arm/arm32/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/cpu.c,v retrieving revision 1.139 diff -p -u -r1.139 cpu.c --- arch/arm/arm32/cpu.c 9 Jan 2020 16:35:03 -0000 1.139 +++ arch/arm/arm32/cpu.c 12 Jan 2020 12:41:10 -0000 @@ -60,6 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.13 #include #include +#include extern const char *cpu_arch; @@ -138,21 +139,7 @@ cpu_attach(device_t dv, cpuid_t id) ci->ci_dev = dv; dv->dv_private = ci; - if (id & MPIDR_MT) { - cpu_topology_set(ci, - __SHIFTOUT(id, MPIDR_AFF2), - __SHIFTOUT(id, MPIDR_AFF1), - __SHIFTOUT(id, MPIDR_AFF0), - 0, - false); - } else { - cpu_topology_set(ci, - __SHIFTOUT(id, MPIDR_AFF1), - __SHIFTOUT(id, MPIDR_AFF0), - 0, - 0, - false); - } + arm_cpu_do_topology(ci); evcnt_attach_dynamic(&ci->ci_arm700bugcount, EVCNT_TYPE_MISC, NULL, xname, "arm700swibug"); Index: arch/arm/conf/files.arm =================================================================== RCS file: /cvsroot/src/sys/arch/arm/conf/files.arm,v retrieving revision 1.149 diff -p -u -r1.149 files.arm --- arch/arm/conf/files.arm 20 Nov 2019 19:37:52 -0000 1.149 +++ arch/arm/conf/files.arm 12 Jan 2020 12:41:10 -0000 @@ -155,6 +155,7 @@ file arch/arm/arm/bus_space_asm_generic. file arch/arm/arm/bus_space_notimpl.S arm32 file arch/arm/arm/arm_machdep.c +file arch/arm/arm/arm_cpu_topology.c file arch/arm/arm/ast.c file arch/arm/arm/bcopyinout.S file arch/arm/arm/blockio.S Index: arch/arm/fdt/cpu_fdt.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/fdt/cpu_fdt.c,v retrieving revision 1.31 diff -p -u -r1.31 cpu_fdt.c --- arch/arm/fdt/cpu_fdt.c 12 Jan 2020 09:29:18 -0000 1.31 +++ arch/arm/fdt/cpu_fdt.c 12 Jan 2020 12:41:10 -0000 @@ -132,6 +132,7 @@ cpu_fdt_attach(device_t parent, device_t sc->sc_dev = self; sc->sc_phandle = phandle; + /* Find the claimed cpu power for this CPU. */ cap_ptr = fdtbus_get_prop(phandle, "capacity-dmips-mhz", &len); if (cap_ptr && len == 4) { prop_dictionary_t dict = device_properties(self); Index: arch/arm/include/cpu.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/include/cpu.h,v retrieving revision 1.103 diff -p -u -r1.103 cpu.h --- arch/arm/include/cpu.h 1 Dec 2019 15:34:44 -0000 1.103 +++ arch/arm/include/cpu.h 12 Jan 2020 12:41:10 -0000 @@ -178,6 +178,8 @@ struct cpu_info { uint32_t ci_midr; uint32_t ci_mpidr; +#define arm_cpu_mpidr(ci) ((ci)->ci_mpidr) + uint32_t ci_capacity_dmips_mhz; struct arm_cache_info * ci_cacheinfo; Index: arch/arm/include/cpu_topology.h =================================================================== RCS file: arch/arm/include/cpu_topology.h diff -N arch/arm/include/cpu_topology.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/arm/include/cpu_topology.h 12 Jan 2020 12:41:10 -0000 @@ -0,0 +1,59 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2020 Matthew R. Green + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ARM_CPU_TOPOLOGY_H_ +#define _ARM_CPU_TOPOLOGY_H_ + +/* + * ARMv7 and ARMv8 compatible CPU topology support. + * + * arm_cpu_do_topology(cpuinfo) + * + * Call arm_cpu_do_topology() in cpu_attach() after making sure that + * arm_cpu_mpidr() will work for this CPU, and it will split up + * package/core/smt IDs. + * + * The CPU frontend can set the "capacity_dmips_mhz" property for + * this CPU device, and arm_cpu_set_topology() will calculate the + * best way to call cpu_topology_set() for the known system. + * + * arm_cpu_topology_set(cpuinfo, mpidr, slow) + * + * arm_cpu_topology_set() is provided for locore and the boot CPU, + * and only works for the current CPU. + */ + +#include +#include + +void arm_cpu_do_topology(struct cpu_info * const); +void arm_cpu_topology_set(struct cpu_info * const, uint64_t, bool); + +#endif /* _ARM_CPU_TOPOLOGY_H_ */ Index: kern/subr_cpu.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_cpu.c,v retrieving revision 1.7 diff -p -u -r1.7 subr_cpu.c --- kern/subr_cpu.c 12 Jan 2020 09:29:18 -0000 1.7 +++ kern/subr_cpu.c 12 Jan 2020 12:41:10 -0000 @@ -192,7 +192,11 @@ cpu_topology_dump(void) enum cpu_rel rel; int i; + CTASSERT(__arraycount(names) >= __arraycount(ci->ci_sibling)); + for (CPU_INFO_FOREACH(cii, ci)) { + if (cpu_topology_haveslow) + printf("%s ", ci->ci_is_slow ? "slow" : "fast"); for (rel = 0; rel < __arraycount(ci->ci_sibling); rel++) { printf("%s has %d %s siblings:", cpu_name(ci), ci->ci_nsibling[rel], names[rel]); @@ -274,6 +278,14 @@ cpu_topology_init(void) ci2->ci_core_id == ci->ci_core_id && ci2->ci_smt_id == ci->ci_smt_id && ci2 != ci) { +#ifdef DEBUG + printf("cpu%u %p pkg %u core %u smt %u same as " + "cpu%u %p pkg %u core %u smt %u\n", + cpu_index(ci), ci, ci->ci_package_id, + ci->ci_core_id, ci->ci_smt_id, + cpu_index(ci2), ci2, ci2->ci_package_id, + ci2->ci_core_id, ci2->ci_smt_id); +#endif printf("cpu_topology_init: info bogus, " "faking it\n"); cpu_topology_fake();