1 /* $NetBSD: rmixl_cpucore.c,v 1.7 2021/08/07 16:18:59 thorpej Exp $ */ 2 3 /* 4 * Copyright 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include "locators.h" 39 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: rmixl_cpucore.c,v 1.7 2021/08/07 16:18:59 thorpej Exp $"); 42 43 #include "opt_multiprocessor.h" 44 45 #include <sys/param.h> 46 #include <sys/device.h> 47 #include <sys/systm.h> 48 #include <sys/cpu.h> 49 50 #include <uvm/uvm_extern.h> 51 52 #include <mips/rmi/rmixlvar.h> 53 #include <mips/rmi/rmixl_cpunodevar.h> 54 #include <mips/rmi/rmixl_cpucorevar.h> 55 #include <mips/rmi/rmixl_fmnvar.h> 56 57 static int cpucore_rmixl_match(device_t, cfdata_t, void *); 58 static void cpucore_rmixl_attach(device_t, device_t, void *); 59 static int cpucore_rmixl_print(void *, const char *); 60 61 CFATTACH_DECL_NEW(cpucore_rmixl, sizeof(struct cpucore_softc), 62 cpucore_rmixl_match, cpucore_rmixl_attach, NULL, NULL); 63 64 static int 65 cpucore_rmixl_match(device_t parent, cfdata_t cf, void *aux) 66 { 67 struct cpunode_attach_args *na = aux; 68 int core = cf->cf_loc[CPUNODECF_CORE]; 69 70 if (!cpu_rmixl(mips_options.mips_cpu)) 71 return 0; 72 73 if (strncmp(na->na_name, cf->cf_name, strlen(cf->cf_name)) == 0 74 #ifndef MULTIPROCESSOR 75 && na->na_core == 0 76 #endif 77 && (core == CPUNODECF_CORE_DEFAULT || core == na->na_core)) 78 return 1; 79 80 return 0; 81 } 82 83 static void 84 cpucore_rmixl_attach(device_t parent, device_t self, void *aux) 85 { 86 struct cpucore_softc * const sc = device_private(self); 87 struct cpunode_attach_args *na = aux; 88 struct cpucore_attach_args ca; 89 u_int nthreads; 90 struct rmixl_config *rcp = &rmixl_configuration; 91 92 sc->sc_dev = self; 93 sc->sc_core = na->na_core; 94 KASSERT(sc->sc_hatched == false); 95 96 #if 0 97 #ifdef MULTIPROCESSOR 98 /* 99 * Create the TLB structure needed - one per core and core0 uses the 100 * default one for the system. 101 */ 102 if (sc->sc_core == 0) { 103 sc->sc_tlbinfo = &pmap_tlb0_info; 104 } else { 105 const vaddr_t va = (vaddr_t)&sc->sc_tlbinfo0; 106 paddr_t pa; 107 108 if (! pmap_extract(pmap_kernel(), va, &pa)) 109 panic("%s: pmap_extract fail, va %#"PRIxVADDR, __func__, va); 110 #ifdef _LP64 111 sc->sc_tlbinfo = (struct pmap_tlb_info *) 112 MIPS_PHYS_TO_XKPHYS_CACHED(pa); 113 #else 114 sc->sc_tlbinfo = (struct pmap_tlb_info *) 115 MIPS_PHYS_TO_KSEG0(pa); 116 #endif 117 pmap_tlb_info_init(sc->sc_tlbinfo); 118 } 119 #endif 120 #endif 121 122 aprint_normal("\n"); 123 aprint_normal_dev(self, "%lu.%02luMHz (hz cycles = %lu, " 124 "delay divisor = %lu)\n", 125 curcpu()->ci_cpu_freq / 1000000, 126 (curcpu()->ci_cpu_freq % 1000000) / 10000, 127 curcpu()->ci_cycles_per_hz, curcpu()->ci_divisor_delay); 128 129 aprint_normal("%s: ", device_xname(self)); 130 cpu_identify(self); 131 132 nthreads = MIPS_CIDFL_RMI_NTHREADS(mips_options.mips_cpu->cpu_cidflags); 133 aprint_normal_dev(self, "%d %s on core\n", nthreads, 134 nthreads == 1 ? "thread" : "threads"); 135 136 /* 137 * Attach CPU (RMI thread contexts) devices 138 * according to userapp_cpu_map bitmask. 139 */ 140 u_int thread_mask = (1 << nthreads) - 1; 141 u_int core_shft = sc->sc_core * nthreads; 142 u_int threads_enb = 143 (u_int)(rcp->rc_psb_info.userapp_cpu_map >> core_shft) & thread_mask; 144 u_int threads_dis = (~threads_enb) & thread_mask; 145 146 sc->sc_threads_dis = threads_dis; 147 if (threads_dis != 0) { 148 aprint_normal_dev(self, "threads"); 149 u_int d = threads_dis; 150 while (d != 0) { 151 const u_int t = ffs(d) - 1; 152 d ^= (1 << t); 153 aprint_normal(" %d%s", t, (d==0) ? "" : ","); 154 } 155 aprint_normal(" offline (disabled by firmware)\n"); 156 } 157 158 u_int threads_try_attach = threads_enb; 159 while (threads_try_attach != 0) { 160 const u_int t = ffs(threads_try_attach) - 1; 161 const u_int bit = 1 << t; 162 threads_try_attach ^= bit; 163 ca.ca_name = "cpu"; 164 ca.ca_thread = t; 165 ca.ca_core = sc->sc_core; 166 if (config_found(self, &ca, cpucore_rmixl_print, 167 CFARGS_NONE) == NULL) { 168 /* 169 * thread did not attach, e.g. not configured 170 * arrange to have it disabled in THREADEN PCR 171 */ 172 threads_enb ^= bit; 173 threads_dis |= bit; 174 } 175 } 176 177 sc->sc_threads_enb = threads_enb; 178 sc->sc_threads_dis = threads_dis; 179 180 /* 181 * when attaching the core of the primary cpu, 182 * do the post-running initialization here 183 */ 184 if (sc->sc_core == RMIXL_CPU_CORE((curcpu()->ci_cpuid))) 185 cpucore_rmixl_run(self); 186 } 187 188 static int 189 cpucore_rmixl_print(void *aux, const char *pnp) 190 { 191 struct cpucore_attach_args *ca = aux; 192 193 if (pnp != NULL) 194 aprint_normal("%s:", pnp); 195 aprint_normal(" thread %d", ca->ca_thread); 196 197 return (UNCONF); 198 } 199 200 /* 201 * cpucore_rmixl_run 202 * called from cpucore_rmixl_attach for primary core 203 * and called from cpu_rmixl_run for each hatched cpu 204 * the first call for each cpucore causes init of per-core features: 205 * - disable unused threads 206 * - set Fine-grained (Round Robin) thread scheduling mode 207 */ 208 void 209 cpucore_rmixl_run(device_t self) 210 { 211 struct cpucore_softc * const sc = device_private(self); 212 213 if (sc->sc_running == false) { 214 sc->sc_running = true; 215 rmixl_mtcr(RMIXL_PCR_THREADEN, sc->sc_threads_enb); 216 rmixl_mtcr(RMIXL_PCR_SCHEDULING, 0); 217 } 218 } 219 220 #ifdef MULTIPROCESSOR 221 /* 222 * cpucore_rmixl_hatch 223 * called from cpu_rmixl_hatch for each cpu 224 * the first call for each cpucore causes init of per-core features 225 */ 226 void 227 cpucore_rmixl_hatch(device_t self) 228 { 229 struct cpucore_softc * const sc = device_private(self); 230 231 if (sc->sc_hatched == false) { 232 /* PCRs for core#0 are set up in mach_init() */ 233 if (sc->sc_core != 0) 234 rmixl_pcr_init_core(); 235 rmixl_fmn_init_core(); 236 sc->sc_hatched = true; 237 } 238 } 239 #endif /* MULTIPROCESSOR */ 240