Module Name: src Committed By: mrg Date: Tue Jan 16 08:23:18 UTC 2018
Modified Files: src/sys/arch/sparc/include: cpu.h src/sys/arch/sparc/sparc: cache.c cache.h cpu.c cpuvar.h pmap.c src/sys/arch/sparc64/include: cpu.h src/sys/arch/sparc64/sparc64: cpu.c src/usr.sbin/cpuctl: cpuctl.c cpuctl.h src/usr.sbin/cpuctl/arch: arm.c i386.c noarch.c Added Files: src/sys/arch/sparc/sparc: cache_print.h src/usr.sbin/cpuctl/arch: sparc.c sparc64.c Log Message: implement cpuctl identify for sparc and sparc64. sparc: - move enum vactype and struct cacheinfo into cpu.h - move the cache flags from cpuinfo.flags into CACHEINFO.c_flags (this allows the new cache_printf_backend() to see them.) remove unused CPUFLG_CACHEIOMMUTABLES and CPUFLG_CACHEDVMA. - align xmpsg to 64 bytes - move cache_print() into cache_print.h so it can be shared with cpuctl. it only depends upon a working printf(). - if found, store the CPU node's "name" into cpu_longname. this changes the default output to show the local CPU not the generic CPU family. eg: cpu0 at mainbus0: mid 8: Ross,RT625 @ 90 MHz, on-chip FPU vs the generic "RT620/625" previously shown. - for each CPU export these things: - name - fpuname - mid - cloc - freq - psr impl and version - mmu impl, version, and number of contexts - cacheinfo structure (which changed for the first time ever with this commit.) sparc64: - add a minimal "cacheinfo" structure to export the i/d/e-cache size and linesize. - store %ver, cpu node "name" and cacheinfo in cpu_info. - set cpu_info ver, name and cacheinfo in cpu_attach(), and export them via sysctl, as well as CPU ID and clock freq cpuctl: - add identifycpu_bind() that returns false on !x86 as their identify routines do not need to run on a particular CPU to obtain its information, and use it to avoid trying to set affinity when not needed. - add sparc and sparc64 cpu identify support using the newly exported values. To generate a diff of this commit: cvs rdiff -u -r1.99 -r1.100 src/sys/arch/sparc/include/cpu.h cvs rdiff -u -r1.99 -r1.100 src/sys/arch/sparc/sparc/cache.c cvs rdiff -u -r1.35 -r1.36 src/sys/arch/sparc/sparc/cache.h cvs rdiff -u -r0 -r1.1 src/sys/arch/sparc/sparc/cache_print.h cvs rdiff -u -r1.250 -r1.251 src/sys/arch/sparc/sparc/cpu.c cvs rdiff -u -r1.94 -r1.95 src/sys/arch/sparc/sparc/cpuvar.h cvs rdiff -u -r1.361 -r1.362 src/sys/arch/sparc/sparc/pmap.c cvs rdiff -u -r1.123 -r1.124 src/sys/arch/sparc64/include/cpu.h cvs rdiff -u -r1.132 -r1.133 src/sys/arch/sparc64/sparc64/cpu.c cvs rdiff -u -r1.28 -r1.29 src/usr.sbin/cpuctl/cpuctl.c cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/cpuctl/cpuctl.h cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/cpuctl/arch/arm.c cvs rdiff -u -r1.79 -r1.80 src/usr.sbin/cpuctl/arch/i386.c cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/cpuctl/arch/noarch.c cvs rdiff -u -r0 -r1.1 src/usr.sbin/cpuctl/arch/sparc.c \ src/usr.sbin/cpuctl/arch/sparc64.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sparc/include/cpu.h diff -u src/sys/arch/sparc/include/cpu.h:1.99 src/sys/arch/sparc/include/cpu.h:1.100 --- src/sys/arch/sparc/include/cpu.h:1.99 Sat Dec 2 00:48:04 2017 +++ src/sys/arch/sparc/include/cpu.h Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.99 2017/12/02 00:48:04 macallan Exp $ */ +/* $NetBSD: cpu.h,v 1.100 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1992, 1993 @@ -56,6 +56,67 @@ * 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; + + int c_flags; +#define CACHE_PAGETABLES 0x1 /* caching pagetables OK on (sun4m) */ +#define CACHE_TRAPPAGEBUG 0x2 /* trap page can't be cached (sun4) */ +#define CACHE_MANDATORY 0x4 /* if cache is on, don't use + uncached access */ +}; + /* Things needed by crash or the kernel */ #if defined(_KERNEL) || defined(_KMEMUSER) @@ -74,9 +135,6 @@ #if defined(_KERNEL) #include <sparc/sparc/cpuvar.h> #include <sparc/sparc/intreg.h> -#else -#include <arch/sparc/sparc/vaddrs.h> -#include <arch/sparc/sparc/cache.h> #endif struct trapframe; @@ -123,9 +181,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 +207,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: src/sys/arch/sparc/sparc/cache.c diff -u src/sys/arch/sparc/sparc/cache.c:1.99 src/sys/arch/sparc/sparc/cache.c:1.100 --- src/sys/arch/sparc/sparc/cache.c:1.99 Mon Jan 15 21:25:25 2018 +++ src/sys/arch/sparc/sparc/cache.c Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cache.c,v 1.99 2018/01/15 21:25:25 mrg Exp $ */ +/* $NetBSD: cache.c,v 1.100 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1996 @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.99 2018/01/15 21:25:25 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.100 2018/01/16 08:23:17 mrg Exp $"); #include "opt_multiprocessor.h" #include "opt_sparc_arch.h" @@ -166,7 +166,7 @@ ms1_cache_enable(void) * MS1 cache is write-through and not write-allocate, so we can * use cacheable access while not displacing cache lines. */ - cpuinfo.flags |= CPUFLG_CACHE_MANDATORY; + CACHEINFO.c_flags |= CACHE_MANDATORY; } void @@ -197,7 +197,7 @@ viking_cache_enable(void) /* Set external cache enable bit in MXCC control register */ stda(MXCC_CTRLREG, ASI_CONTROL, ldda(MXCC_CTRLREG, ASI_CONTROL) | MXCC_CTRLREG_CE); - cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; /* Ok to cache PTEs */ + CACHEINFO.c_flags |= CACHE_PAGETABLES; /* Ok to cache PTEs */ CACHEINFO.ec_enabled = 1; } } Index: src/sys/arch/sparc/sparc/cache.h diff -u src/sys/arch/sparc/sparc/cache.h:1.35 src/sys/arch/sparc/sparc/cache.h:1.36 --- src/sys/arch/sparc/sparc/cache.h:1.35 Sun Mar 4 06:00:45 2007 +++ src/sys/arch/sparc/sparc/cache.h Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cache.h,v 1.35 2007/03/04 06:00:45 christos Exp $ */ +/* $NetBSD: cache.h,v 1.36 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1996 @@ -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: src/sys/arch/sparc/sparc/cpu.c diff -u src/sys/arch/sparc/sparc/cpu.c:1.250 src/sys/arch/sparc/sparc/cpu.c:1.251 --- src/sys/arch/sparc/sparc/cpu.c:1.250 Sat Dec 2 00:48:05 2017 +++ src/sys/arch/sparc/sparc/cpu.c Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.250 2017/12/02 00:48:05 macallan Exp $ */ +/* $NetBSD: cpu.c,v 1.251 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1996 @@ -52,7 +52,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.250 2017/12/02 00:48:05 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.251 2018/01/16 08:23:17 mrg Exp $"); #include "opt_multiprocessor.h" #include "opt_lockdebug.h" @@ -68,6 +68,8 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.25 #include <sys/xcall.h> #include <sys/ipi.h> #include <sys/cpu.h> +#include <sys/sysctl.h> +#include <sys/kmem.h> #include <uvm/uvm.h> @@ -89,6 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.25 #include <sparc/sparc/asm.h> #include <sparc/sparc/cpuvar.h> #include <sparc/sparc/memreg.h> +#include <sparc/sparc/cache_print.h> #if defined(SUN4D) #include <sparc/sparc/cpuunitvar.h> #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,59 +1047,14 @@ fpu_init(struct cpu_info *sc) } } -void +static void cache_print(struct cpu_softc *sc) { struct cacheinfo *ci = &sc->sc_cpuinfo->cacheinfo; - if (sc->sc_cpuinfo->flags & CPUFLG_SUN4CACHEBUG) - 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)); } - /*------------*/ @@ -1316,7 +1329,7 @@ void sun4_hotfix(struct cpu_info *sc) { - if ((sc->flags & CPUFLG_SUN4CACHEBUG) != 0) + if ((sc->cacheinfo.c_flags & CACHE_TRAPPAGEBUG) != 0) kvm_uncache((char *)trapbase, 1); /* Use the hardware-assisted page flush routine, if present */ @@ -1783,7 +1796,7 @@ static int mxcc = -1; /* Test if we're directly on the MBus */ if ((pcr & VIKING_PCR_MB) == 0) { sc->mxcc = 1; - sc->flags |= CPUFLG_CACHE_MANDATORY; + sc->cacheinfo.c_flags |= CACHE_MANDATORY; sc->zero_page = pmap_zero_page_viking_mxcc; sc->copy_page = pmap_copy_page_viking_mxcc; #if !defined(MSIIEP) @@ -1797,7 +1810,7 @@ static int mxcc = -1; if ((pcr & VIKING_PCR_TC) == 0) printf("[viking: PCR_TC is off]"); else - sc->flags |= CPUFLG_CACHEPAGETABLES; + sc->cacheinfo.c_flags |= CACHE_PAGETABLES; } else { #ifdef MULTIPROCESSOR if (sparc_ncpus > 1 && sc->cacheinfo.ec_totalsize == 0) @@ -1829,7 +1842,7 @@ viking_mmu_enable(void) printf("[viking: turn on PCR_TC]"); } pcr |= VIKING_PCR_TC; - cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; + CACHEINFO.c_flags |= CACHE_PAGETABLES; } else pcr &= ~VIKING_PCR_TC; sta(SRMMU_PCR, ASI_SRMMU, pcr); @@ -2074,6 +2087,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: src/sys/arch/sparc/sparc/cpuvar.h diff -u src/sys/arch/sparc/sparc/cpuvar.h:1.94 src/sys/arch/sparc/sparc/cpuvar.h:1.95 --- src/sys/arch/sparc/sparc/cpuvar.h:1.94 Sat Dec 10 10:41:07 2016 +++ src/sys/arch/sparc/sparc/cpuvar.h Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuvar.h,v 1.94 2016/12/10 10:41:07 mrg Exp $ */ +/* $NetBSD: cpuvar.h,v 1.95 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -154,12 +154,6 @@ struct module_info { /* * CPU flags */ -#define CPUFLG_CACHEPAGETABLES 0x1 /* caching pagetables OK on Sun4m */ -#define CPUFLG_CACHEIOMMUTABLES 0x2 /* caching IOMMU translations OK */ -#define CPUFLG_CACHEDVMA 0x4 /* DVMA goes through cache */ -#define CPUFLG_SUN4CACHEBUG 0x8 /* trap page can't be cached */ -#define CPUFLG_CACHE_MANDATORY 0x10 /* if cache is on, don't use - uncached access */ #define CPUFLG_HATCHED 0x1000 /* CPU is alive */ #define CPUFLG_PAUSED 0x2000 /* CPU is paused */ #define CPUFLG_GOTMSG 0x4000 /* CPU got an lev13 IPI */ Index: src/sys/arch/sparc/sparc/pmap.c diff -u src/sys/arch/sparc/sparc/pmap.c:1.361 src/sys/arch/sparc/sparc/pmap.c:1.362 --- src/sys/arch/sparc/sparc/pmap.c:1.361 Thu Dec 22 14:47:59 2016 +++ src/sys/arch/sparc/sparc/pmap.c Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.361 2016/12/22 14:47:59 cherry Exp $ */ +/* $NetBSD: pmap.c,v 1.362 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1996 @@ -56,7 +56,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.361 2016/12/22 14:47:59 cherry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.362 2018/01/16 08:23:17 mrg Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -902,7 +902,7 @@ setpte4m(vaddr_t va, int pte) void * pgt_page_alloc(struct pool *pp, int flags) { - int cacheit = (cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0; + int cacheit = (CACHEINFO.c_flags & CACHE_PAGETABLES) != 0; struct vm_page *pg; vaddr_t va; paddr_t pa; @@ -3844,7 +3844,7 @@ pmap_bootstrap4m(void *top) pte |= PPROT_N_RX | SRMMU_TEPTE; /* Deal with the cacheable bit for pagetable memory */ - if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0 || + if ((CACHEINFO.c_flags & CACHE_PAGETABLES) != 0 || q < pagetables_start || q >= pagetables_end) pte |= SRMMU_PG_C; @@ -3856,7 +3856,7 @@ pmap_bootstrap4m(void *top) pmap_kernel()->pm_stats.resident_count++; } - if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0) { + if ((CACHEINFO.c_flags & CACHE_PAGETABLES) == 0) { /* * The page tables have been setup. Since we're still * running on the PROM's memory map, the memory we @@ -4026,7 +4026,7 @@ pmap_alloc_cpu(struct cpu_info *sc) int pagesz = NBPG; int i; - cachebit = (cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0; + cachebit = (CACHEINFO.c_flags & CACHE_PAGETABLES) != 0; /* * Allocate properly aligned and contiguous physically memory @@ -7143,7 +7143,7 @@ pmap_zero_page4m(paddr_t pa) pcache_flush_page(pa, 1); } pte = SRMMU_TEPTE | PPROT_N_RWX | (pa >> SRMMU_PPNPASHIFT); - if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY) + if (CACHEINFO.c_flags & CACHE_MANDATORY) pte |= SRMMU_PG_C; va = cpuinfo.vpage[0]; @@ -7258,7 +7258,7 @@ pmap_copy_page4m(paddr_t src, paddr_t ds } dpte = SRMMU_TEPTE | PPROT_N_RWX | (dst >> SRMMU_PPNPASHIFT); - if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY) + if (CACHEINFO.c_flags & CACHE_MANDATORY) dpte |= SRMMU_PG_C; sva = cpuinfo.vpage[0]; Index: src/sys/arch/sparc64/include/cpu.h diff -u src/sys/arch/sparc64/include/cpu.h:1.123 src/sys/arch/sparc64/include/cpu.h:1.124 --- src/sys/arch/sparc64/include/cpu.h:1.123 Fri Feb 10 23:26:23 2017 +++ src/sys/arch/sparc64/include/cpu.h Tue Jan 16 08:23:17 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.123 2017/02/10 23:26:23 palle Exp $ */ +/* $NetBSD: cpu.h,v 1.124 2018/01/16 08:23:17 mrg Exp $ */ /* * Copyright (c) 1992, 1993 @@ -53,6 +53,18 @@ #define CPU_VIS 5 /* 0 - no VIS, 1 - VIS 1.0, etc. */ #define CPU_MAXID 6 /* number of valid machdep ids */ +/* + * This is exported via sysctl for cpuctl(8). + */ +struct cacheinfo { + int c_itotalsize; + int c_ilinesize; + int c_dtotalsize; + int c_dlinesize; + int c_etotalsize; + int c_elinesize; +}; + #if defined(_KERNEL) || defined(_KMEMUSER) /* * Exported definitions unique to SPARC cpu support. @@ -128,8 +140,14 @@ struct cpu_info { int ci_cpuid; + uint64_t ci_ver; + /* CPU PROM information. */ u_int ci_node; + const char *ci_name; + + /* This is for sysctl. */ + struct cacheinfo ci_cacheinfo; /* %tick and cpu frequency information */ u_long ci_tick_increment; Index: src/sys/arch/sparc64/sparc64/cpu.c diff -u src/sys/arch/sparc64/sparc64/cpu.c:1.132 src/sys/arch/sparc64/sparc64/cpu.c:1.133 --- src/sys/arch/sparc64/sparc64/cpu.c:1.132 Mon Sep 11 19:25:07 2017 +++ src/sys/arch/sparc64/sparc64/cpu.c Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.132 2017/09/11 19:25:07 palle Exp $ */ +/* $NetBSD: cpu.c,v 1.133 2018/01/16 08:23:18 mrg Exp $ */ /* * Copyright (c) 1996 @@ -52,7 +52,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.132 2017/09/11 19:25:07 palle Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.133 2018/01/16 08:23:18 mrg Exp $"); #include "opt_multiprocessor.h" @@ -62,6 +62,8 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.13 #include <sys/kernel.h> #include <sys/reboot.h> #include <sys/cpu.h> +#include <sys/sysctl.h> +#include <sys/kmem.h> #include <uvm/uvm.h> @@ -412,6 +414,61 @@ cpu_reset_fpustate(void) savefpstate(fpstate); } +/* setup the hw.cpuN.* nodes for this cpu */ +static void +cpu_setup_sysctl(struct cpu_info *ci, device_t dev) +{ + const struct sysctlnode *cpunode = NULL; + + sysctl_createv(NULL, 0, NULL, &cpunode, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, device_xname(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->ci_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("id", &ci->ci_cpuid); +#undef SETUPI + +#define SETUPQ(name, member) \ + sysctl_createv(NULL, 0, &cpunode, NULL, \ + CTLFLAG_PERMANENT, \ + CTLTYPE_QUAD, name, NULL, \ + NULL, 0, member, 0, \ + CTL_CREATE, CTL_EOL); + + SETUPQ("clock_frequency", &ci->ci_cpu_clockrate[0]) + SETUPQ("ver", &ci->ci_ver) +#undef SETUPI + + sysctl_createv(NULL, 0, &cpunode, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRUCT, "cacheinfo", NULL, + NULL, 0, &ci->ci_cacheinfo, sizeof(ci->ci_cacheinfo), + CTL_CREATE, CTL_EOL); + +} + /* * Attach the CPU. * Discover interesting goop about the virtual address cache @@ -485,12 +542,14 @@ cpu_attach(device_t parent, device_t dev ci->ci_system_clockrate[0] = sclk; ci->ci_system_clockrate[1] = sclk / 1000000; - snprintf(buf, sizeof buf, "%s @ %s MHz", - prom_getpropstring(node, "name"), clockfreq(clk)); + ci->ci_name = kmem_strdupsize(prom_getpropstring(node, "name"), NULL, + KM_NOSLEEP); + snprintf(buf, sizeof buf, "%s @ %s MHz", ci->ci_name, clockfreq(clk)); cpu_setmodel("%s (%s)", machine_model, buf); aprint_normal(": %s, CPU id %d\n", buf, ci->ci_cpuid); aprint_naive("\n"); + ci->ci_ver = getver(); if (CPU_ISSUN4U || CPU_ISSUN4US) { aprint_normal_dev(dev, "manuf %x, impl %x, mask %x\n", (u_int)GETVER_CPU_MANUF(), @@ -532,6 +591,8 @@ cpu_attach(device_t parent, device_t dev (long)linesize); sep = ", "; } + ci->ci_cacheinfo.c_itotalsize = totalsize; + ci->ci_cacheinfo.c_ilinesize = linesize; dcachesize = cpu_dcache_size(node); if (dcachesize > dcache_size) @@ -559,6 +620,8 @@ cpu_attach(device_t parent, device_t dev (long)linesize); sep = ", "; } + ci->ci_cacheinfo.c_dtotalsize = totalsize; + ci->ci_cacheinfo.c_dlinesize = linesize; linesize = l = cpu_ecache_line_size(node); for (i = 0; (1 << i) < l && l; i++) @@ -580,11 +643,15 @@ cpu_attach(device_t parent, device_t dev (long)linesize); } aprint_normal("\n"); + ci->ci_cacheinfo.c_etotalsize = totalsize; + ci->ci_cacheinfo.c_elinesize = linesize; if (ecache_min_line_size == 0 || linesize < ecache_min_line_size) ecache_min_line_size = linesize; + cpu_setup_sysctl(ci, dev); + /* * Now that we know the size of the largest cache on this CPU, * re-color our pages. Index: src/usr.sbin/cpuctl/cpuctl.c diff -u src/usr.sbin/cpuctl/cpuctl.c:1.28 src/usr.sbin/cpuctl/cpuctl.c:1.29 --- src/usr.sbin/cpuctl/cpuctl.c:1.28 Mon Nov 16 03:34:50 2015 +++ src/usr.sbin/cpuctl/cpuctl.c Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuctl.c,v 1.28 2015/11/16 03:34:50 mrg Exp $ */ +/* $NetBSD: cpuctl.c,v 1.29 2018/01/16 08:23:18 mrg Exp $ */ /*- * Copyright (c) 2007, 2008, 2009, 2012, 2015 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #ifndef lint #include <sys/cdefs.h> -__RCSID("$NetBSD: cpuctl.c,v 1.28 2015/11/16 03:34:50 mrg Exp $"); +__RCSID("$NetBSD: cpuctl.c,v 1.29 2018/01/16 08:23:18 mrg Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -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: src/usr.sbin/cpuctl/cpuctl.h diff -u src/usr.sbin/cpuctl/cpuctl.h:1.5 src/usr.sbin/cpuctl/cpuctl.h:1.6 --- src/usr.sbin/cpuctl/cpuctl.h:1.5 Mon Dec 23 12:35:33 2013 +++ src/usr.sbin/cpuctl/cpuctl.h Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuctl.h,v 1.5 2013/12/23 12:35:33 msaitoh Exp $ */ +/* $NetBSD: cpuctl.h,v 1.6 2018/01/16 08:23:18 mrg Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -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: src/usr.sbin/cpuctl/arch/arm.c diff -u src/usr.sbin/cpuctl/arch/arm.c:1.1 src/usr.sbin/cpuctl/arch/arm.c:1.2 --- src/usr.sbin/cpuctl/arch/arm.c:1.1 Thu Jan 31 23:40:48 2013 +++ src/usr.sbin/cpuctl/arch/arm.c Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: arm.c,v 1.1 2013/01/31 23:40:48 matt Exp $ */ +/* $NetBSD: arm.c,v 1.2 2018/01/16 08:23:18 mrg Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: arm.c,v 1.1 2013/01/31 23:40:48 matt Exp $"); +__RCSID("$NetBSD: arm.c,v 1.2 2018/01/16 08:23:18 mrg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -210,6 +210,13 @@ print_features(const char *cpuname, cons } } +bool +identifycpu_bind(void) +{ + + return false; +} + void identifycpu(int fd, const char *cpuname) { Index: src/usr.sbin/cpuctl/arch/i386.c diff -u src/usr.sbin/cpuctl/arch/i386.c:1.79 src/usr.sbin/cpuctl/arch/i386.c:1.80 --- src/usr.sbin/cpuctl/arch/i386.c:1.79 Wed Jan 10 07:08:35 2018 +++ src/usr.sbin/cpuctl/arch/i386.c Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: i386.c,v 1.79 2018/01/10 07:08:35 msaitoh Exp $ */ +/* $NetBSD: i386.c,v 1.80 2018/01/16 08:23:18 mrg Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: i386.c,v 1.79 2018/01/10 07:08:35 msaitoh Exp $"); +__RCSID("$NetBSD: i386.c,v 1.80 2018/01/16 08:23:18 mrg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -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: src/usr.sbin/cpuctl/arch/noarch.c diff -u src/usr.sbin/cpuctl/arch/noarch.c:1.5 src/usr.sbin/cpuctl/arch/noarch.c:1.6 --- src/usr.sbin/cpuctl/arch/noarch.c:1.5 Wed Oct 17 20:22:15 2012 +++ src/usr.sbin/cpuctl/arch/noarch.c Tue Jan 16 08:23:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: noarch.c,v 1.5 2012/10/17 20:22:15 drochner Exp $ */ +/* $NetBSD: noarch.c,v 1.6 2018/01/16 08:23:18 mrg Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: noarch.c,v 1.5 2012/10/17 20:22:15 drochner Exp $"); +__RCSID("$NetBSD: noarch.c,v 1.6 2018/01/16 08:23:18 mrg Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -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) { Added files: Index: src/sys/arch/sparc/sparc/cache_print.h diff -u /dev/null src/sys/arch/sparc/sparc/cache_print.h:1.1 --- /dev/null Tue Jan 16 08:23:18 2018 +++ src/sys/arch/sparc/sparc/cache_print.h Tue Jan 16 08:23:17 2018 @@ -0,0 +1,87 @@ +/* $NetBSD: cache_print.h,v 1.1 2018/01/16 08:23:17 mrg Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Paul Kranenburg. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * 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) +{ + + if (ci->c_flags & CACHE_TRAPPAGEBUG) + printf("%s: cache chip bug; trap page uncached\n", 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: src/usr.sbin/cpuctl/arch/sparc.c diff -u /dev/null src/usr.sbin/cpuctl/arch/sparc.c:1.1 --- /dev/null Tue Jan 16 08:23:18 2018 +++ src/usr.sbin/cpuctl/arch/sparc.c Tue Jan 16 08:23:18 2018 @@ -0,0 +1,100 @@ +/* $NetBSD: sparc.c,v 1.1 2018/01/16 08:23:18 mrg Exp $ */ + +/* + * 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 <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: sparc.c,v 1.1 2018/01/16 08:23:18 mrg Exp $"); +#endif + +#include <sys/types.h> +#include <sys/cpuio.h> +#include <sys/sysctl.h> + +#include <machine/cpu.h> + +#include <stdio.h> +#include <err.h> + +#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; +} Index: src/usr.sbin/cpuctl/arch/sparc64.c diff -u /dev/null src/usr.sbin/cpuctl/arch/sparc64.c:1.1 --- /dev/null Tue Jan 16 08:23:18 2018 +++ src/usr.sbin/cpuctl/arch/sparc64.c Tue Jan 16 08:23:18 2018 @@ -0,0 +1,129 @@ +/* $NetBSD: sparc64.c,v 1.1 2018/01/16 08:23:18 mrg Exp $ */ + +/* + * 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 <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: sparc64.c,v 1.1 2018/01/16 08:23:18 mrg Exp $"); +#endif + +#include <sys/types.h> +#include <sys/cpuio.h> +#include <sys/sysctl.h> + +#include <machine/cpu.h> +#include <machine/psl.h> + +#include <stdio.h> +#include <err.h> + +#include "../cpuctl.h" + +void +identifycpu(int fd, const char *cpuname) +{ + char path[128]; + char *name; + const char *sep; + uint64_t ver; + uint64_t hz; + int cpu_arch, id; + 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.id", cpuname); + len = sizeof(id); + if (sysctlbyname(path, &id, &len, 0, 0) == -1) + err(1, "couldn't get %s", path); + + snprintf(path, sizeof path, "hw.%s.ver", cpuname); + len = sizeof(ver); + if (sysctlbyname(path, &ver, &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); + + printf("%s: %s @ %ld MHz, CPU id %d\n", cpuname, name, hz / 1000000, id); + printf("%s: manuf %x, impl %x, mask %x\n", cpuname, + (unsigned)((ver & VER_MASK) >> VER_MASK_SHIFT), + (unsigned)((ver & VER_IMPL) >> VER_IMPL_SHIFT), + (unsigned)((ver & VER_MANUF) >> VER_MANUF_SHIFT)); + printf("%s: ", cpuname); + + sep = ""; + if (cacheinfo.c_itotalsize) { + printf("%s%ldK instruction (%ld b/l)", sep, + (long)cacheinfo.c_itotalsize/1024, + (long)cacheinfo.c_ilinesize); + sep = ", "; + } + if (cacheinfo.c_dtotalsize) { + printf("%s%ldK data (%ld b/l)", sep, + (long)cacheinfo.c_dtotalsize/1024, + (long)cacheinfo.c_dlinesize); + sep = ", "; + } + + if (cacheinfo.c_etotalsize) { + printf("%s%ldK external (%ld b/l)", sep, + (long)cacheinfo.c_etotalsize/1024, + (long)cacheinfo.c_elinesize); + } + printf("\n"); + + 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; +}