Index: sys/arch/sparc/include/cpu.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/include/cpu.h,v retrieving revision 1.99 diff -p -u -u -r1.99 cpu.h --- sys/arch/sparc/include/cpu.h 2 Dec 2017 00:48:04 -0000 1.99 +++ sys/arch/sparc/include/cpu.h 15 Jan 2018 09:53:09 -0000 @@ -56,6 +56,61 @@ * Exported definitions unique to SPARC cpu support. */ +/* + * Sun-4 and Sun-4c virtual address cache. + * + * Sun-4 virtual caches come in two flavors, write-through (Sun-4c) + * and write-back (Sun-4). The write-back caches are much faster + * but require a bit more care. + * + * This is exported via sysctl so be careful changing it. + */ +enum vactype { VAC_UNKNOWN, VAC_NONE, VAC_WRITETHROUGH, VAC_WRITEBACK }; + +/* + * Cache control information. + * + * This is exported via sysctl so be careful changing it. + */ + +struct cacheinfo { + int c_totalsize; /* total size, in bytes */ + /* if split, MAX(icache,dcache) */ + int c_enabled; /* true => cache is enabled */ + int c_hwflush; /* true => have hardware flush */ + int c_linesize; /* line size, in bytes */ + /* if split, MIN(icache,dcache) */ + int c_l2linesize; /* log2(linesize) */ + int c_nlines; /* precomputed # of lines to flush */ + int c_physical; /* true => cache has physical + address tags */ + int c_associativity; /* # of "buckets" in cache line */ + int c_split; /* true => cache is split */ + + int ic_totalsize; /* instruction cache */ + int ic_enabled; + int ic_linesize; + int ic_l2linesize; + int ic_nlines; + int ic_associativity; + + int dc_totalsize; /* data cache */ + int dc_enabled; + int dc_linesize; + int dc_l2linesize; + int dc_nlines; + int dc_associativity; + + int ec_totalsize; /* external cache info */ + int ec_enabled; + int ec_linesize; + int ec_l2linesize; + int ec_nlines; + int ec_associativity; + + enum vactype c_vactype; +}; + /* Things needed by crash or the kernel */ #if defined(_KERNEL) || defined(_KMEMUSER) @@ -74,9 +129,6 @@ #if defined(_KERNEL) #include #include -#else -#include -#include #endif struct trapframe; @@ -123,9 +175,9 @@ struct cpu_info { /* * Primary Inter-processor message area. Keep this aligned * to a cache line boundary if possible, as the structure - * itself is one (normal 32 byte) cache-line. + * itself is one or less (32/64 byte) cache-line. */ - struct xpmsg msg __aligned(32); + struct xpmsg msg __aligned(64); /* Scheduler flags */ int ci_want_ast; @@ -149,7 +201,7 @@ struct cpu_info { paddr_t ctx_tbl_pa; /* [4m] ctx table physical address */ /* Cache information */ - struct cacheinfo cacheinfo; /* see cache.h */ + struct cacheinfo cacheinfo; /* see above */ /* various flags to workaround anomalies in chips */ volatile int flags; /* see CPUFLG_xxx, below */ Index: sys/arch/sparc/sparc/cache.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cache.h,v retrieving revision 1.35 diff -p -u -u -r1.35 cache.h --- sys/arch/sparc/sparc/cache.h 4 Mar 2007 06:00:45 -0000 1.35 +++ sys/arch/sparc/sparc/cache.h 15 Jan 2018 09:53:09 -0000 @@ -51,16 +51,6 @@ #endif /* - * Sun-4 and Sun-4c virtual address cache. - * - * Sun-4 virtual caches come in two flavors, write-through (Sun-4c) - * and write-back (Sun-4). The write-back caches are much faster - * but require a bit more care. - * - */ -enum vactype { VAC_UNKNOWN, VAC_NONE, VAC_WRITETHROUGH, VAC_WRITEBACK }; - -/* * Cache tags can be written in control space, and must be set to 0 * (or invalid anyway) before turning on the cache. The tags are * addressed as an array of 32-bit structures of the form: @@ -234,47 +224,6 @@ void smp_vcache_flush_page(int va,int); #define pcache_flush_page(pa,flag) cpuinfo.pcache_flush_page(pa,flag) -/* - * Cache control information. - */ -struct cacheinfo { - int c_totalsize; /* total size, in bytes */ - /* if split, MAX(icache,dcache) */ - int c_enabled; /* true => cache is enabled */ - int c_hwflush; /* true => have hardware flush */ - int c_linesize; /* line size, in bytes */ - /* if split, MIN(icache,dcache) */ - int c_l2linesize; /* log2(linesize) */ - int c_nlines; /* precomputed # of lines to flush */ - int c_physical; /* true => cache has physical - address tags */ - int c_associativity; /* # of "buckets" in cache line */ - int c_split; /* true => cache is split */ - - int ic_totalsize; /* instruction cache */ - int ic_enabled; - int ic_linesize; - int ic_l2linesize; - int ic_nlines; - int ic_associativity; - - int dc_totalsize; /* data cache */ - int dc_enabled; - int dc_linesize; - int dc_l2linesize; - int dc_nlines; - int dc_associativity; - - int ec_totalsize; /* external cache info */ - int ec_enabled; - int ec_linesize; - int ec_l2linesize; - int ec_nlines; - int ec_associativity; - - enum vactype c_vactype; -}; - #define CACHEINFO cpuinfo.cacheinfo #endif /* SPARC_CACHE_H */ Index: sys/arch/sparc/sparc/cache_print.h =================================================================== RCS file: sys/arch/sparc/sparc/cache_print.h diff -N sys/arch/sparc/sparc/cache_print.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/sparc/sparc/cache_print.h 15 Jan 2018 09:53:09 -0000 @@ -0,0 +1,107 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1996 + * The President and Fellows of Harvard College. All rights reserved. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Harvard University. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Aaron Brown and + * Harvard University. + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)cpu.c 8.5 (Berkeley) 11/23/93 + * + * from: NetBSD: cpu.c,v 1.250 2017/12/02 00:48:05 macallan Exp + */ + +/* + * This works for kernel and cpuctl(8). It only relies upon having + * a working printf() in the environment. + */ + +static void cache_printf_backend(struct cacheinfo *ci, const char *cpuname); + +static void +cache_printf_backend(struct cacheinfo *ci, const char *cpuname) +{ + + printf("%s: ", cpuname); + + if (ci->c_totalsize == 0) { + printf("no cache\n"); + return; + } + + if (ci->c_split) { + const char *sep = ""; + + printf("%s", (ci->c_physical ? "physical " : "")); + if (ci->ic_totalsize > 0) { + printf("%s%dK instruction (%d b/l)", sep, + ci->ic_totalsize/1024, ci->ic_linesize); + sep = ", "; + } + if (ci->dc_totalsize > 0) { + printf("%s%dK data (%d b/l)", sep, + ci->dc_totalsize/1024, ci->dc_linesize); + } + } else if (ci->c_physical) { + /* combined, physical */ + printf("physical %dK combined cache (%d bytes/line)", + ci->c_totalsize/1024, ci->c_linesize); + } else { + /* combined, virtual */ + printf("%dK byte write-%s, %d bytes/line, %cw flush", + ci->c_totalsize/1024, + (ci->c_vactype == VAC_WRITETHROUGH) ? "through" : "back", + ci->c_linesize, + ci->c_hwflush ? 'h' : 's'); + } + + if (ci->ec_totalsize > 0) { + printf(", %dK external (%d b/l)", + ci->ec_totalsize/1024, ci->ec_linesize); + } + printf(": "); + if (ci->c_enabled) + printf("cache enabled"); + printf("\n"); +} Index: sys/arch/sparc/sparc/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v retrieving revision 1.250 diff -p -u -u -r1.250 cpu.c --- sys/arch/sparc/sparc/cpu.c 2 Dec 2017 00:48:05 -0000 1.250 +++ sys/arch/sparc/sparc/cpu.c 15 Jan 2018 09:53:09 -0000 @@ -68,6 +68,8 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.25 #include #include #include +#include +#include #include @@ -89,6 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.25 #include #include #include +#include #if defined(SUN4D) #include #endif @@ -131,11 +134,12 @@ CFATTACH_DECL_NEW(cpu_cpuunit, sizeof(st cpu_cpuunit_match, cpu_cpuunit_attach, NULL, NULL); #endif /* SUN4D */ -static void cpu_init_evcnt(struct cpu_info *cpi); +static void cpu_setup_sysctl(struct cpu_softc *); +static void cpu_init_evcnt(struct cpu_info *); static void cpu_attach(struct cpu_softc *, int, int); static const char *fsrtoname(int, int, int); -void cache_print(struct cpu_softc *); +static void cache_print(struct cpu_softc *); void cpu_setup(void); void fpu_init(struct cpu_info *); @@ -383,6 +387,58 @@ cpu_init_evcnt(struct cpu_info *cpi) } } +/* setup the hw.cpuN.* nodes for this cpu */ +static void +cpu_setup_sysctl(struct cpu_softc *sc) +{ + struct cpu_info *ci = sc->sc_cpuinfo; + const struct sysctlnode *cpunode = NULL; + + sysctl_createv(NULL, 0, NULL, &cpunode, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, device_xname(sc->sc_dev), NULL, + NULL, 0, NULL, 0, + CTL_HW, + CTL_CREATE, CTL_EOL); + + if (cpunode == NULL) + return; + +#define SETUPS(name, member) \ + sysctl_createv(NULL, 0, &cpunode, NULL, \ + CTLFLAG_PERMANENT, \ + CTLTYPE_STRING, name, NULL, \ + NULL, 0, member, 0, \ + CTL_CREATE, CTL_EOL); + + SETUPS("name", __UNCONST(ci->cpu_longname)) + SETUPS("fpuname", __UNCONST(ci->fpu_name)) +#undef SETUPS + +#define SETUPI(name, member) \ + sysctl_createv(NULL, 0, &cpunode, NULL, \ + CTLFLAG_PERMANENT, \ + CTLTYPE_INT, name, NULL, \ + NULL, 0, member, 0, \ + CTL_CREATE, CTL_EOL); + + SETUPI("mid", &ci->mid) + SETUPI("clock_frequency", &ci->hz) + SETUPI("psr_implementation", &ci->cpu_impl) + SETUPI("psr_version", &ci->cpu_vers) + SETUPI("mmu_implementation", &ci->mmu_impl) + SETUPI("mmu_version", &ci->mmu_vers) + SETUPI("mmu_nctx", &ci->mmu_ncontext) +#undef SETUPI + + sysctl_createv(NULL, 0, &cpunode, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRUCT, "cacheinfo", NULL, + NULL, 0, &ci->cacheinfo, sizeof(ci->cacheinfo), + CTL_CREATE, CTL_EOL); + +} + /* * Attach the CPU. * Discover interesting goop about the virtual address cache @@ -432,6 +488,7 @@ cpu_attach(struct cpu_softc *sc, int nod if (cpu_attach_count > 1) { cpu_attach_non_boot(sc, cpi, node); cpu_init_evcnt(cpi); + cpu_setup_sysctl(sc); return; } #endif /* MULTIPROCESSOR */ @@ -445,6 +502,7 @@ cpu_attach(struct cpu_softc *sc, int nod cpu_setmodel("%s (%s)", machine_model, buf); printf(": %s\n", buf); cache_print(sc); + cpu_setup_sysctl(sc); cpi->master = 1; cpi->eintstack = eintstack; @@ -989,7 +1047,7 @@ fpu_init(struct cpu_info *sc) } } -void +static void cache_print(struct cpu_softc *sc) { struct cacheinfo *ci = &sc->sc_cpuinfo->cacheinfo; @@ -998,50 +1056,9 @@ cache_print(struct cpu_softc *sc) printf("%s: cache chip bug; trap page uncached\n", device_xname(sc->sc_dev)); - printf("%s: ", device_xname(sc->sc_dev)); - - if (ci->c_totalsize == 0) { - printf("no cache\n"); - return; - } - - if (ci->c_split) { - const char *sep = ""; - - printf("%s", (ci->c_physical ? "physical " : "")); - if (ci->ic_totalsize > 0) { - printf("%s%dK instruction (%d b/l)", sep, - ci->ic_totalsize/1024, ci->ic_linesize); - sep = ", "; - } - if (ci->dc_totalsize > 0) { - printf("%s%dK data (%d b/l)", sep, - ci->dc_totalsize/1024, ci->dc_linesize); - } - } else if (ci->c_physical) { - /* combined, physical */ - printf("physical %dK combined cache (%d bytes/line)", - ci->c_totalsize/1024, ci->c_linesize); - } else { - /* combined, virtual */ - printf("%dK byte write-%s, %d bytes/line, %cw flush", - ci->c_totalsize/1024, - (ci->c_vactype == VAC_WRITETHROUGH) ? "through" : "back", - ci->c_linesize, - ci->c_hwflush ? 'h' : 's'); - } - - if (ci->ec_totalsize > 0) { - printf(", %dK external (%d b/l)", - ci->ec_totalsize/1024, ci->ec_linesize); - } - printf(": "); - if (ci->c_enabled) - printf("cache enabled"); - printf("\n"); + cache_printf_backend(ci, device_xname(sc->sc_dev)); } - /*------------*/ @@ -2074,6 +2091,17 @@ getcpuinfo(struct cpu_info *sc, int node mmu_vers = prom_getpropint(node, "version", -1); } + if (node != 0) { + char *cpu_name; + char namebuf[64]; + + cpu_name = prom_getpropstringA(node, "name", namebuf, + sizeof namebuf); + if (cpu_name && cpu_name[0]) + sc->cpu_longname = kmem_strdupsize(cpu_name, NULL, + KM_NOSLEEP); + } + for (mp = cpu_conf; ; mp++) { if (mp->arch != cputyp && mp->arch != ANY) continue; Index: usr.sbin/cpuctl/cpuctl.c =================================================================== RCS file: /cvsroot/src/usr.sbin/cpuctl/cpuctl.c,v retrieving revision 1.28 diff -p -u -u -r1.28 cpuctl.c --- usr.sbin/cpuctl/cpuctl.c 16 Nov 2015 03:34:50 -0000 1.28 +++ usr.sbin/cpuctl/cpuctl.c 15 Jan 2018 09:53:09 -0000 @@ -254,7 +254,6 @@ cpu_ucode(char **argv) } } - static void cpu_identify(char **argv) { @@ -267,7 +266,7 @@ cpu_identify(char **argv) id = getcpuid(*argv); snprintf(name, sizeof(name), "cpu%u", id); - if (np != 1) { + if (identifycpu_bind() && np != 1) { cpuset = cpuset_create(); if (cpuset == NULL) err(EXIT_FAILURE, "cpuset_create"); Index: usr.sbin/cpuctl/cpuctl.h =================================================================== RCS file: /cvsroot/src/usr.sbin/cpuctl/cpuctl.h,v retrieving revision 1.5 diff -p -u -u -r1.5 cpuctl.h --- usr.sbin/cpuctl/cpuctl.h 23 Dec 2013 12:35:33 -0000 1.5 +++ usr.sbin/cpuctl/cpuctl.h 15 Jan 2018 09:53:09 -0000 @@ -34,6 +34,7 @@ int aprint_verbose_dev(const char *, con int aprint_error_dev(const char *, const char *, ...) __printflike(2, 3); void identifycpu(int, const char *); +bool identifycpu_bind(void); int ucodeupdate_check(int, struct cpu_ucode *); extern int verbose; Index: usr.sbin/cpuctl/arch/arm.c =================================================================== RCS file: /cvsroot/src/usr.sbin/cpuctl/arch/arm.c,v retrieving revision 1.1 diff -p -u -u -r1.1 arm.c --- usr.sbin/cpuctl/arch/arm.c 31 Jan 2013 23:40:48 -0000 1.1 +++ usr.sbin/cpuctl/arch/arm.c 15 Jan 2018 09:53:09 -0000 @@ -210,6 +210,13 @@ print_features(const char *cpuname, cons } } +bool +identifycpu_bind(void) +{ + + return false; +} + void identifycpu(int fd, const char *cpuname) { Index: usr.sbin/cpuctl/arch/i386.c =================================================================== RCS file: /cvsroot/src/usr.sbin/cpuctl/arch/i386.c,v retrieving revision 1.79 diff -p -u -u -r1.79 i386.c --- usr.sbin/cpuctl/arch/i386.c 10 Jan 2018 07:08:35 -0000 1.79 +++ usr.sbin/cpuctl/arch/i386.c 15 Jan 2018 09:53:09 -0000 @@ -2235,6 +2235,13 @@ powernow_probe(struct cpu_info *ci) buf); } +bool +identifycpu_bind(void) +{ + + return true; +} + int ucodeupdate_check(int fd, struct cpu_ucode *uc) { Index: usr.sbin/cpuctl/arch/noarch.c =================================================================== RCS file: /cvsroot/src/usr.sbin/cpuctl/arch/noarch.c,v retrieving revision 1.5 diff -p -u -u -r1.5 noarch.c --- usr.sbin/cpuctl/arch/noarch.c 17 Oct 2012 20:22:15 -0000 1.5 +++ usr.sbin/cpuctl/arch/noarch.c 15 Jan 2018 09:53:09 -0000 @@ -45,6 +45,13 @@ identifycpu(int fd, const char *cpuname) printf("CPU identification not implemented for this architecture.\n"); } +bool +identifycpu_bind(void) +{ + + return false; +} + int ucodeupdate_check(int fd, struct cpu_ucode *uc) { Index: usr.sbin/cpuctl/arch/sparc.c =================================================================== RCS file: usr.sbin/cpuctl/arch/sparc.c diff -N usr.sbin/cpuctl/arch/sparc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.sbin/cpuctl/arch/sparc.c 15 Jan 2018 09:53:09 -0000 @@ -0,0 +1,100 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2018 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 + +#ifndef lint +__RCSID("$NetBSD$"); +#endif + +#include +#include +#include + +#include + +#include +#include + +#include "../cpuctl.h" +#include "../../../sys/arch/sparc/sparc/cache_print.h" + +void +identifycpu(int fd, const char *cpuname) +{ + char path[128]; + char *name; + char *fpuname; + int cpu_arch, mid, hz; + struct cacheinfo cacheinfo; + size_t len; + + len = sizeof(cpu_arch); + if (sysctlbyname("machdep.cpu_arch", &cpu_arch, &len, 0, 0) == -1) + err(1, "couldn't get machdep.cpu_arch"); + + snprintf(path, sizeof path, "hw.%s.cacheinfo", cpuname); + len = sizeof(cacheinfo); + if (sysctlbyname(path, &cacheinfo, &len, 0, 0) == -1) + err(1, "couldn't get %s", path); + + snprintf(path, sizeof path, "hw.%s.mid", cpuname); + len = sizeof(mid); + if (sysctlbyname(path, &mid, &len, 0, 0) == -1) + err(1, "couldn't get %s", path); + + snprintf(path, sizeof path, "hw.%s.clock_frequency", cpuname); + len = sizeof(hz); + if (sysctlbyname(path, &hz, &len, 0, 0) == -1) + err(1, "couldn't get %s", path); + snprintf(path, sizeof path, "hw.%s.name", cpuname); + name = asysctlbyname(path, &len); + + snprintf(path, sizeof path, "hw.%s.fpuname", cpuname); + fpuname = asysctlbyname(path, &len); + + printf("%s: mid %d: %s @ %d MHz, %s FPU\n", cpuname, mid, name, hz / 1000000, fpuname); + cache_printf_backend(&cacheinfo, cpuname); + + printf("%s: SPARC v%d\n", cpuname, cpu_arch); +} + +bool +identifycpu_bind(void) +{ + + return false; +} + +int +ucodeupdate_check(int fd, struct cpu_ucode *uc) +{ + + return 0; +}