1 /* $NetBSD: mips_machdep.c,v 1.310 2026/07/01 17:01:43 rkujawa 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 /* 39 * Copyright 2000, 2001 40 * Broadcom Corporation. All rights reserved. 41 * 42 * This software is furnished under license and may be used and copied only 43 * in accordance with the following terms and conditions. Subject to these 44 * conditions, you may download, copy, install, use, modify and distribute 45 * modified or unmodified copies of this software in source and/or binary 46 * form. No title or ownership is transferred hereby. 47 * 48 * 1) Any source code used, modified or distributed must reproduce and 49 * retain this copyright notice and list of conditions as they appear in 50 * the source file. 51 * 52 * 2) No right is granted to use any trade name, trademark, or logo of 53 * Broadcom Corporation. The "Broadcom Corporation" name may not be 54 * used to endorse or promote products derived from this software 55 * without the prior written permission of Broadcom Corporation. 56 * 57 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 58 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 59 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 60 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 61 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 62 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 63 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 64 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 65 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 66 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 67 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70 /*- 71 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 72 * All rights reserved. 73 * 74 * This code is derived from software contributed to The NetBSD Foundation 75 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 76 * NASA Ames Research Center and by Chris Demetriou. 77 * 78 * Redistribution and use in source and binary forms, with or without 79 * modification, are permitted provided that the following conditions 80 * are met: 81 * 1. Redistributions of source code must retain the above copyright 82 * notice, this list of conditions and the following disclaimer. 83 * 2. Redistributions in binary form must reproduce the above copyright 84 * notice, this list of conditions and the following disclaimer in the 85 * documentation and/or other materials provided with the distribution. 86 * 87 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 88 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 89 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 90 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 91 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 92 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 93 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 94 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 95 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 96 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 97 * POSSIBILITY OF SUCH DAMAGE. 98 */ 99 100 /* 101 * Copyright 1996 The Board of Trustees of The Leland Stanford 102 * Junior University. All Rights Reserved. 103 * 104 * Permission to use, copy, modify, and distribute this 105 * software and its documentation for any purpose and without 106 * fee is hereby granted, provided that the above copyright 107 * notice appear in all copies. Stanford University 108 * makes no representations about the suitability of this 109 * software for any purpose. It is provided "as is" without 110 * express or implied warranty. 111 */ 112 113 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 114 __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.310 2026/07/01 17:01:43 rkujawa Exp $"); 115 116 #define __INTR_PRIVATE 117 #include "opt_cputype.h" 118 #include "opt_compat_netbsd32.h" 119 #include "opt_multiprocessor.h" 120 121 #include <sys/param.h> 122 #include <sys/systm.h> 123 #include <sys/proc.h> 124 #include <sys/intr.h> 125 #include <sys/exec.h> 126 #include <sys/reboot.h> 127 #include <sys/module.h> 128 #include <sys/mount.h> /* fsid_t for syscallargs */ 129 #include <sys/lwp.h> 130 #include <sys/sysctl.h> 131 #include <sys/msgbuf.h> 132 #include <sys/conf.h> 133 #include <sys/core.h> 134 #include <sys/device.h> 135 #include <sys/kcore.h> 136 #include <sys/kmem.h> 137 #include <sys/ras.h> 138 #include <sys/cpu.h> 139 #include <sys/atomic.h> 140 #include <sys/ucontext.h> 141 #include <sys/bitops.h> 142 143 #include <mips/kcore.h> 144 145 #ifdef COMPAT_NETBSD32 146 #include <compat/netbsd32/netbsd32.h> 147 #endif 148 149 #include <uvm/uvm.h> 150 #include <uvm/uvm_physseg.h> 151 152 #include <dev/cons.h> 153 #include <dev/mm.h> 154 155 #include <mips/pcb.h> 156 #include <mips/cache.h> 157 #include <mips/frame.h> 158 #include <mips/regnum.h> 159 #include <mips/mips_opcode.h> 160 161 #include <mips/cpu.h> 162 #include <mips/locore.h> 163 #include <mips/psl.h> 164 #include <mips/pte.h> 165 #include <mips/userret.h> 166 167 #ifdef __HAVE_BOOTINFO_H 168 #include <machine/bootinfo.h> 169 #endif 170 171 #ifdef MIPS64_OCTEON 172 #include <mips/cavium/octeonvar.h> 173 #endif 174 175 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 176 #include <mips/mipsNN.h> /* MIPS32/MIPS64 registers */ 177 178 #define _MKINSN(a,b,c,d,e) ((uint32_t)(((a) << 26)|((b) << 21)|((c) << 16)|((d) << 11)|(e))) 179 180 #ifdef _LP64 181 #define _LOAD_V0_L_PRIVATE_A0 _MKINSN(OP_LD, _R_A0, _R_V0, 0, offsetof(lwp_t, l_private)) 182 #define _MTC0_V0_USERLOCAL _MKINSN(OP_COP0, OP_DMT, _R_V0, MIPS_COP_0_TLB_CONTEXT, 2) 183 #else 184 #define _LOAD_V0_L_PRIVATE_A0 _MKINSN(OP_LW, _R_A0, _R_V0, 0, offsetof(lwp_t, l_private)) 185 #define _MTC0_V0_USERLOCAL _MKINSN(OP_COP0, OP_MT, _R_V0, MIPS_COP_0_TLB_CONTEXT, 2) 186 #endif 187 #define JR_RA _MKINSN(OP_SPECIAL, _R_RA, 0, 0, OP_JR) 188 189 #endif 190 191 /* Internal routines. */ 192 int cpu_dumpsize(void); 193 u_long cpu_dump_mempagecnt(void); 194 int cpu_dump(void); 195 196 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 197 static void mips_watchpoint_init(void); 198 #endif 199 200 #if defined(_LP64) && defined(ENABLE_MIPS_16KB_PAGE) 201 vaddr_t mips_vm_maxuser_address = MIPS_VM_MAXUSER_ADDRESS; 202 #endif 203 204 #if defined(MIPS3_PLUS) 205 uint32_t mips3_cp0_tlb_page_mask_probe(void); 206 uint64_t mips3_cp0_tlb_entry_hi_probe(void); 207 uint64_t mips3_cp0_tlb_entry_lo_probe(void); 208 209 static void mips3_tlb_probe(void); 210 #endif 211 212 #if defined(MIPS1) 213 static void mips1_vector_init(const struct splsw *); 214 extern const struct locoresw mips1_locoresw; 215 extern const mips_locore_jumpvec_t mips1_locore_vec; 216 #endif 217 218 #if defined(MIPS3) 219 static void mips3_vector_init(const struct splsw *); 220 extern const struct locoresw mips3_locoresw; 221 extern const mips_locore_jumpvec_t mips3_locore_vec; 222 #endif 223 224 #if defined(MIPS3_LOONGSON2) 225 static void loongson2_vector_init(const struct splsw *); 226 extern const struct locoresw loongson2_locoresw; 227 extern const mips_locore_jumpvec_t loongson2_locore_vec; 228 #endif 229 230 #if defined(MIPS32) 231 static void mips32_vector_init(const struct splsw *); 232 extern const struct locoresw mips32_locoresw; 233 extern const mips_locore_jumpvec_t mips32_locore_vec; 234 #endif 235 236 #if defined(MIPS32R2) 237 static void mips32r2_vector_init(const struct splsw *); 238 extern const struct locoresw mips32r2_locoresw; 239 extern const mips_locore_jumpvec_t mips32r2_locore_vec; 240 #endif 241 242 #if defined(MIPS64) 243 static void mips64_vector_init(const struct splsw *); 244 extern const struct locoresw mips64_locoresw; 245 extern const mips_locore_jumpvec_t mips64_locore_vec; 246 #endif 247 248 #if defined(MIPS64R2) 249 extern const struct locoresw mips64r2_locoresw; 250 extern const mips_locore_jumpvec_t mips64r2_locore_vec; 251 #endif 252 253 #if defined(PARANOIA) 254 void std_splsw_test(void); 255 #endif 256 257 mips_locore_jumpvec_t mips_locore_jumpvec; 258 259 struct locoresw mips_locoresw; 260 261 extern const struct splsw std_splsw; 262 struct splsw mips_splsw; 263 264 struct mips_options mips_options = { 265 .mips_cpu_id = 0xffffffff, 266 .mips_fpu_id = 0xffffffff, 267 }; 268 269 void * msgbufaddr; 270 271 /* the following is used by DDB to reset the system */ 272 void (*cpu_reset_address)(void); 273 274 /* the following is used externally (sysctl_hw) */ 275 char machine[] = MACHINE; /* from <machine/param.h> */ 276 char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 277 278 /* 279 * Assumptions: 280 * - All MIPS3+ have an r4k-style MMU. _Many_ assumptions throughout 281 * much of the mips code about this. Includes overloaded usage of 282 * MIPS3_PLUS. 283 * - All MIPS3+ use the same exception model (cp0 status, cause bits, 284 * etc). _Many_ assumptions throughout much of the mips code about 285 * this. Includes overloaded usage of MIPS3_PLUS. 286 * - All MIPS3+ have a count register. MIPS_HAS_CLOCK in <mips/cpu.h> 287 * will need to be revised if this is false. 288 */ 289 #define MIPS32_FLAGS CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_USE_WAIT 290 #define MIPS64_FLAGS MIPS32_FLAGS /* same as MIPS32 flags (for now) */ 291 292 static const struct pridtab cputab[] = { 293 { 0, MIPS_R2000, -1, -1, CPU_ARCH_MIPS1, 64, 294 CPU_MIPS_NO_LLSC, 0, 0, "MIPS R2000 CPU" }, 295 { 0, MIPS_R3000, MIPS_REV_R2000A, -1, CPU_ARCH_MIPS1, 64, 296 CPU_MIPS_NO_LLSC, 0, 0, "MIPS R2000A CPU" }, 297 { 0, MIPS_R3000, MIPS_REV_R3000, -1, CPU_ARCH_MIPS1, 64, 298 CPU_MIPS_NO_LLSC, 0, 0, "MIPS R3000 CPU" }, 299 { 0, MIPS_R3000, MIPS_REV_R3000A, -1, CPU_ARCH_MIPS1, 64, 300 CPU_MIPS_NO_LLSC, 0, 0, "MIPS R3000A CPU" }, 301 { 0, MIPS_R6000, -1, -1, CPU_ARCH_MIPS2, 32, 302 MIPS_NOT_SUPP, 0, 0, "MIPS R6000 CPU" }, 303 304 /* 305 * rev 0x00, 0x22 and 0x30 are R4000, 0x40, 0x50 and 0x60 are R4400. 306 * should we allow ranges and use 0x00 - 0x3f for R4000 and 307 * 0x40 - 0xff for R4400? 308 */ 309 { 0, MIPS_R4000, MIPS_REV_R4000_A, -1, CPU_ARCH_MIPS3, 48, 310 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 311 "MIPS R4000 CPU" }, 312 { 0, MIPS_R4000, MIPS_REV_R4000_B, -1, CPU_ARCH_MIPS3, 48, 313 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 314 "MIPS R4000 CPU" }, 315 { 0, MIPS_R4000, MIPS_REV_R4000_C, -1, CPU_ARCH_MIPS3, 48, 316 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 317 "MIPS R4000 CPU" }, 318 { 0, MIPS_R4000, MIPS_REV_R4400_A, -1, CPU_ARCH_MIPS3, 48, 319 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 320 "MIPS R4400 CPU" }, 321 { 0, MIPS_R4000, MIPS_REV_R4400_B, -1, CPU_ARCH_MIPS3, 48, 322 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 323 "MIPS R4400 CPU" }, 324 { 0, MIPS_R4000, MIPS_REV_R4400_C, -1, CPU_ARCH_MIPS3, 48, 325 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 326 "MIPS R4400 CPU" }, 327 328 { 0, MIPS_R3LSI, -1, -1, CPU_ARCH_MIPS1, -1, 329 MIPS_NOT_SUPP, 0, 0, "LSI Logic R3000 derivative" }, 330 { 0, MIPS_R6000A, -1, -1, CPU_ARCH_MIPS2, 32, 331 MIPS_NOT_SUPP, 0, 0, "MIPS R6000A CPU" }, 332 { 0, MIPS_R3IDT, -1, -1, CPU_ARCH_MIPS1, -1, 333 MIPS_NOT_SUPP, 0, 0, "IDT R3041 or RC36100 CPU" }, 334 { 0, MIPS_R4100, -1, -1, CPU_ARCH_MIPS3, 32, 335 CPU_MIPS_R4K_MMU | CPU_MIPS_NO_LLSC, 0, 0, 336 "NEC VR4100 CPU" }, 337 { 0, MIPS_R4200, -1, -1, CPU_ARCH_MIPS3, -1, 338 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 339 "NEC VR4200 CPU" }, 340 { 0, MIPS_R4300, -1, -1, CPU_ARCH_MIPS3, 32, 341 CPU_MIPS_R4K_MMU, 0, 0, "NEC VR4300 CPU" }, 342 { 0, MIPS_R4600, -1, -1, CPU_ARCH_MIPS3, 48, 343 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 344 "QED R4600 Orion CPU" }, 345 { 0, MIPS_R4700, -1, -1, CPU_ARCH_MIPS3, 48, 346 CPU_MIPS_R4K_MMU, 0, 0, "QED R4700 Orion CPU" }, 347 348 { 0, MIPS_R8000, -1, -1, CPU_ARCH_MIPS4, 384, 349 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 350 "MIPS R8000 Blackbird/TFP CPU" }, 351 { 0, MIPS_R10000, -1, -1, CPU_ARCH_MIPS4, 64, 352 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 353 "MIPS R10000 CPU" }, 354 { 0, MIPS_R12000, -1, -1, CPU_ARCH_MIPS4, 64, 355 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 356 "MIPS R12000 CPU" }, 357 { 0, MIPS_R14000, -1, -1, CPU_ARCH_MIPS4, 64, 358 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 359 "MIPS R14000 CPU" }, 360 361 /* XXX 362 * If the Processor Revision ID of the 4650 isn't 0, the following 363 * entry needs to be adjusted. Can't use a wildcard match because 364 * the TX39 series processors share the same Processor ID value. 365 * Or maybe put TX39 CPUs first if the revid doesn't overlap with 366 * the 4650... 367 */ 368 { 0, MIPS_R4650, 0, -1, CPU_ARCH_MIPS3, -1, 369 MIPS_NOT_SUPP /* no MMU! */, 0, 0, "QED R4650 CPU" }, 370 { 0, MIPS_TX3900, MIPS_REV_TX3912, -1, CPU_ARCH_MIPS1, 32, 371 CPU_MIPS_NO_LLSC, 0, 0, "Toshiba TX3912 CPU" }, 372 { 0, MIPS_TX3900, MIPS_REV_TX3922, -1, CPU_ARCH_MIPS1, 64, 373 CPU_MIPS_NO_LLSC, 0, 0, "Toshiba TX3922 CPU" }, 374 { 0, MIPS_TX3900, MIPS_REV_TX3927, -1, CPU_ARCH_MIPS1, 64, 375 CPU_MIPS_NO_LLSC, 0, 0, "Toshiba TX3927 CPU" }, 376 { 0, MIPS_R5000, -1, -1, CPU_ARCH_MIPS4, 48, 377 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 378 "MIPS R5000 CPU" }, 379 { 0, MIPS_RM5200, -1, -1, CPU_ARCH_MIPS4, 48, 380 CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT | 381 CPU_MIPS_USE_WAIT, 0, 0, "QED RM5200 CPU" }, 382 383 /* XXX 384 * The rm7000 rev 2.0 can have 64 tlbs, and has 6 extra interrupts. See 385 * "Migrating to the RM7000 from other MIPS Microprocessors" 386 * for more details. 387 */ 388 { 0, MIPS_RM7000, -1, -1, CPU_ARCH_MIPS4, 48, 389 MIPS_NOT_SUPP | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT | 390 CPU_MIPS_USE_WAIT, 0, 0, "QED RM7000 CPU" }, 391 392 /* 393 * IDT RC32300 core is a 32 bit MIPS2 processor with 394 * MIPS3/MIPS4 extensions. It has an R4000-style TLB, 395 * while all registers are 32 bits and any 64 bit 396 * instructions like ld/sd/dmfc0/dmtc0 are not allowed. 397 * 398 * note that the Config register has a non-standard base 399 * for IC and DC (2^9 instead of 2^12). 400 * 401 */ 402 { 0, MIPS_RC32300, -1, -1, CPU_ARCH_MIPS3, 16, 403 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 404 "IDT RC32300 CPU" }, 405 { 0, MIPS_RC32364, -1, -1, CPU_ARCH_MIPS3, 16, 406 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 407 "IDT RC32364 CPU" }, 408 { 0, MIPS_RC64470, -1, -1, CPU_ARCH_MIPSx, -1, 409 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 410 "IDT RC64474/RC64475 CPU" }, 411 412 { 0, MIPS_R5400, -1, -1, CPU_ARCH_MIPSx, -1, 413 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, 0, 0, 414 "NEC VR5400 CPU" }, 415 { 0, MIPS_R5900, -1, -1, CPU_ARCH_MIPS3, 48, 416 CPU_MIPS_NO_LLSC | CPU_MIPS_R4K_MMU, 0, 0, 417 "Toshiba R5900 CPU" }, 418 419 { 0, MIPS_TX4900, MIPS_REV_TX4927, -1, CPU_ARCH_MIPS3, 48, 420 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 421 "Toshiba TX4927 CPU" }, 422 423 { 0, MIPS_TX4900, -1, -1, CPU_ARCH_MIPS3, 48, 424 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 0, 0, 425 "Toshiba TX4900 CPU" }, 426 427 /* 428 * ICT Loongson2 is a MIPS64 CPU with a few quirks. For some reason 429 * the virtual aliases present with 4KB pages make the caches misbehave 430 * so we make all accesses uncached. With 16KB pages, no virtual 431 * aliases are possible so we can use caching. 432 */ 433 #ifdef ENABLE_MIPS_16KB_PAGE 434 #define MIPS_LOONGSON2_CCA 0 435 #else 436 #define MIPS_LOONGSON2_CCA (CPU_MIPS_HAVE_SPECIAL_CCA | \ 437 (2 << CPU_MIPS_CACHED_CCA_SHIFT)) 438 #endif 439 { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2E, -1, CPU_ARCH_MIPS3, 64, 440 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2 441 | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2E CPU" }, 442 { 0, MIPS_LOONGSON2, MIPS_REV_LOONGSON2F, -1, CPU_ARCH_MIPS3, 64, 443 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT | CPU_MIPS_LOONGSON2 444 | MIPS_LOONGSON2_CCA, 0, 0, "ICT Loongson 2F CPU" }, 445 446 #if 0 /* ID collisions : can we use a CU1 test or similar? */ 447 { 0, MIPS_R3SONY, -1, -1, CPU_ARCH_MIPS1, -1, 448 MIPS_NOT_SUPP, 0, 0, "SONY R3000 derivative" }, /* 0x21; crash R4700? */ 449 { 0, MIPS_R3NKK, -1, -1, CPU_ARCH_MIPS1, -1, 450 MIPS_NOT_SUPP, 0, 0, "NKK R3000 derivative" }, /* 0x23; crash R5000? */ 451 #endif 452 453 { MIPS_PRID_CID_MTI, MIPS_4Kc, -1, -1, -1, 0, 454 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4Kc" }, 455 { MIPS_PRID_CID_MTI, MIPS_4KEc, -1, -1, -1, 0, 456 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KEc" }, 457 { MIPS_PRID_CID_MTI, MIPS_4KEc_R2, -1, -1, -1, 0, 458 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KEc (Rev 2)" }, 459 { MIPS_PRID_CID_MTI, MIPS_4KSc, -1, -1, -1, 0, 460 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "4KSc" }, 461 { MIPS_PRID_CID_MTI, MIPS_5Kc, -1, -1, -1, 0, 462 MIPS64_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "5Kc" }, 463 { MIPS_PRID_CID_MTI, MIPS_20Kc, -1, -1, -1, 0, 464 MIPS64_FLAGS, 0, 0, "20Kc" }, 465 { MIPS_PRID_CID_MTI, MIPS_25Kf, -1, -1, -1, 0, 466 MIPS64_FLAGS, 0, 0, "25Kf" }, 467 { MIPS_PRID_CID_MTI, MIPS_24K, -1, -1, -1, 0, 468 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 469 MIPS_CP0FL_USE | 470 MIPS_CP0FL_EBASE | 471 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 472 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7, 473 0, "24K" }, 474 { MIPS_PRID_CID_MTI, MIPS_24KE, -1, -1, -1, 0, 475 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 476 MIPS_CP0FL_USE | 477 MIPS_CP0FL_EBASE | 478 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 479 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7, 480 0, "24KE" }, 481 { MIPS_PRID_CID_MTI, MIPS_34K, -1, -1, -1, 0, 482 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 483 MIPS_CP0FL_USE | 484 MIPS_CP0FL_EBASE | 485 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 486 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG7, 487 0, "34K" }, 488 { MIPS_PRID_CID_MTI, MIPS_74K, -1, -1, -1, 0, 489 CPU_MIPS_HAVE_SPECIAL_CCA | (0 << CPU_MIPS_CACHED_CCA_SHIFT) | 490 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 491 MIPS_CP0FL_USE | 492 MIPS_CP0FL_EBASE | 493 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 494 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7, 495 0, "74K" }, 496 { MIPS_PRID_CID_MTI, MIPS_1004K, -1, -1, -1, 0, 497 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 498 MIPS_CP0FL_USE | 499 MIPS_CP0FL_EBASE | 500 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 501 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7, 502 0, "1004K" }, 503 { MIPS_PRID_CID_MTI, MIPS_1074K, -1, -1, -1, 0, 504 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 505 MIPS_CP0FL_USE | 506 MIPS_CP0FL_EBASE | 507 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 508 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7, 509 0, "1074K" }, 510 511 { MIPS_PRID_CID_BROADCOM, MIPS_BCM3302, -1, -1, -1, 0, 512 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 0, 0, "BCM3302" }, 513 514 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1000, -1, 0, 515 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 516 "Au1000 (Rev 1 core)" }, 517 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1000, -1, 0, 518 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 519 "Au1000 (Rev 2 core)" }, 520 521 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1100, -1, 0, 522 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 523 "Au1100 (Rev 1 core)" }, 524 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1100, -1, 0, 525 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 526 "Au1100 (Rev 2 core)" }, 527 528 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV1, -1, MIPS_AU1500, -1, 0, 529 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 530 "Au1500 (Rev 1 core)" }, 531 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1500, -1, 0, 532 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 533 "Au1500 (Rev 2 core)" }, 534 535 { MIPS_PRID_CID_ALCHEMY, MIPS_AU_REV2, -1, MIPS_AU1550, -1, 0, 536 MIPS32_FLAGS | CPU_MIPS_NO_WAIT | CPU_MIPS_I_D_CACHE_COHERENT, 0, 0, 537 "Au1550 (Rev 2 core)" }, 538 539 /* The SB-1 CPU uses a CCA of 5 - "Cacheable Coherent Shareable" */ 540 { MIPS_PRID_CID_SIBYTE, MIPS_SB1, -1, -1, -1, 0, 541 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | 542 CPU_MIPS_HAVE_SPECIAL_CCA | 543 (CCA_SB_CACHEABLE_COHERENT << CPU_MIPS_CACHED_CCA_SHIFT), 0, 0, 544 "SB-1" }, 545 { MIPS_PRID_CID_SIBYTE, MIPS_SB1_11, -1, -1, -1, 0, 546 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | 547 CPU_MIPS_HAVE_SPECIAL_CCA | 548 (CCA_SB_CACHEABLE_COHERENT << CPU_MIPS_CACHED_CCA_SHIFT), 0, 0, 549 "SB-1 (0x11)" }, 550 551 { MIPS_PRID_CID_RMI, MIPS_XLR732B, -1, -1, -1, 0, 552 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 553 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 554 MIPS_CP0FL_USE | 555 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 556 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 557 CIDFL_RMI_TYPE_XLR|MIPS_CIDFL_RMI_CPUS(8,4)|MIPS_CIDFL_RMI_L2(2MB), 558 "XLR732B" }, 559 560 { MIPS_PRID_CID_RMI, MIPS_XLR732C, -1, -1, -1, 0, 561 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 562 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 563 MIPS_CP0FL_USE | 564 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 565 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 566 CIDFL_RMI_TYPE_XLR|MIPS_CIDFL_RMI_CPUS(8,4)|MIPS_CIDFL_RMI_L2(2MB), 567 "XLR732C" }, 568 569 { MIPS_PRID_CID_RMI, MIPS_XLS616, -1, -1, -1, 0, 570 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 571 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 572 MIPS_CP0FL_USE | 573 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 574 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 575 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(4,4)|MIPS_CIDFL_RMI_L2(1MB), 576 "XLS616" }, 577 578 { MIPS_PRID_CID_RMI, MIPS_XLS416, -1, -1, -1, 0, 579 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 580 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 581 MIPS_CP0FL_USE | 582 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 583 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 584 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(4,4)|MIPS_CIDFL_RMI_L2(1MB), 585 "XLS416" }, 586 587 { MIPS_PRID_CID_RMI, MIPS_XLS408, -1, -1, -1, 0, 588 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 589 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 590 MIPS_CP0FL_USE | 591 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 592 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 593 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(1MB), 594 "XLS408" }, 595 596 { MIPS_PRID_CID_RMI, MIPS_XLS408LITE, -1, -1, -1, 0, 597 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 598 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 599 MIPS_CP0FL_USE | 600 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 601 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 602 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(1MB), 603 "XLS408lite" }, 604 605 { MIPS_PRID_CID_RMI, MIPS_XLS404LITE, -1, -1, -1, 0, 606 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 607 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 608 MIPS_CP0FL_USE | 609 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 610 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 611 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(512KB), 612 "XLS404lite" }, 613 614 { MIPS_PRID_CID_RMI, MIPS_XLS208, -1, -1, -1, 0, 615 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 616 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 617 MIPS_CP0FL_USE | 618 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 619 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 620 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(512KB), 621 "XLS208" }, 622 623 { MIPS_PRID_CID_RMI, MIPS_XLS204, -1, -1, -1, 0, 624 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 625 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 626 MIPS_CP0FL_USE | 627 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 628 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 629 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(256KB), 630 "XLS204" }, 631 632 { MIPS_PRID_CID_RMI, MIPS_XLS108, -1, -1, -1, 0, 633 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 634 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 635 MIPS_CP0FL_USE | 636 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 637 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 638 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(2,4)|MIPS_CIDFL_RMI_L2(512KB), 639 "XLS108" }, 640 641 { MIPS_PRID_CID_RMI, MIPS_XLS104, -1, -1, -1, 0, 642 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR | 643 CPU_MIPS_I_D_CACHE_COHERENT | CPU_MIPS_HAVE_MxCR, 644 MIPS_CP0FL_USE | 645 MIPS_CP0FL_EIRR | MIPS_CP0FL_EIMR | MIPS_CP0FL_EBASE | 646 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG7, 647 CIDFL_RMI_TYPE_XLS|MIPS_CIDFL_RMI_CPUS(1,4)|MIPS_CIDFL_RMI_L2(256KB), 648 "XLS104" }, 649 650 { MIPS_PRID_CID_CAVIUM, MIPS_CN31XX, -1, -1, -1, 0, 651 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR, 652 MIPS_CP0FL_USE | 653 MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG | 654 MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3, 655 0, 656 "CN31xx" }, 657 658 { MIPS_PRID_CID_CAVIUM, MIPS_CN30XX, -1, -1, -1, 0, 659 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR, 660 MIPS_CP0FL_USE | 661 MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG | 662 MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3, 663 0, 664 "CN30xx" }, 665 666 { MIPS_PRID_CID_CAVIUM, MIPS_CN50XX, -1, -1, -1, 0, 667 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR, 668 MIPS_CP0FL_USE | 669 MIPS_CP0FL_EBASE | MIPS_CP0FL_CONFIG | 670 MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | MIPS_CP0FL_CONFIG3, 671 0, 672 "CN50xx" }, 673 674 { MIPS_PRID_CID_CAVIUM, MIPS_CN68XX, -1, -1, -1, 0, 675 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR, 676 MIPS_CP0FL_USE | 677 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 678 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG4, 679 0, 680 "CN68xx" }, 681 682 { MIPS_PRID_CID_CAVIUM, MIPS_CN70XX, -1, -1, -1, 0, 683 MIPS64_FLAGS | CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_NO_LLADDR, 684 MIPS_CP0FL_USE | MIPS_CP0FL_EBASE | 685 MIPS_CP0FL_CONFIG | MIPS_CP0FL_CONFIG1 | MIPS_CP0FL_CONFIG2 | 686 MIPS_CP0FL_CONFIG3 | MIPS_CP0FL_CONFIG4 | MIPS_CP0FL_CONFIG5 | 687 MIPS_CP0FL_CONFIG6 | MIPS_CP0FL_CONFIG7, 688 0, 689 "CN70xx/CN71xx" }, 690 691 /* Microsoft Research' extensible MIPS */ 692 { MIPS_PRID_CID_MICROSOFT, MIPS_eMIPS, 1, -1, CPU_ARCH_MIPS1, 64, 693 CPU_MIPS_NO_WAIT, 0, 0, "eMIPS CPU" }, 694 695 /* 696 * Ingenic XBurst (e.g. JZ4780). 697 */ 698 { MIPS_PRID_CID_INGENIC, MIPS_XBURST, -1, -1, -1, 0, 699 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, 700 0, 0, "XBurst" }, 701 702 { 0, 0, 0, 0, 0, 0, 703 0, 0, 0, NULL } 704 }; 705 706 static const struct pridtab fputab[] = { 707 { 0, MIPS_SOFT, -1, 0, 0, 0, 0, 0, 0, "software emulated floating point" }, 708 { 0, MIPS_R2360, -1, 0, 0, 0, 0, 0, 0, "MIPS R2360 Floating Point Board" }, 709 { 0, MIPS_R2010, -1, 0, 0, 0, 0, 0, 0, "MIPS R2010 FPC" }, 710 { 0, MIPS_R3010, -1, 0, 0, 0, 0, 0, 0, "MIPS R3010 FPC" }, 711 { 0, MIPS_R6010, -1, 0, 0, 0, 0, 0, 0, "MIPS R6010 FPC" }, 712 { 0, MIPS_R4010, -1, 0, 0, 0, 0, 0, 0, "MIPS R4010 FPC" }, 713 }; 714 715 /* 716 * Company ID's are not sparse (yet), this array is indexed directly 717 * by pridtab->cpu_cid. 718 */ 719 static const char * const cidnames[] = { 720 "Prehistoric", 721 "MIPS", /* or "MIPS Technologies, Inc. */ 722 "Broadcom", /* or "Broadcom Corp." */ 723 "Alchemy", /* or "Alchemy Semiconductor" */ 724 "SiByte", /* or "Broadcom Corp. (SiByte)" */ 725 "SandCraft", 726 "Phillips", 727 "Toshiba or Microsoft", 728 "LSI", 729 "(unannounced)", 730 "(unannounced)", 731 "Lexra", 732 "RMI", 733 "Cavium", 734 }; 735 #define ncidnames __arraycount(cidnames) 736 737 #if defined(MIPS1) 738 /* 739 * MIPS-I locore function vector 740 */ 741 742 static void 743 mips1_vector_init(const struct splsw *splsw) 744 { 745 extern char mips1_utlb_miss[], mips1_utlb_miss_end[]; 746 extern char mips1_exception[], mips1_exception_end[]; 747 748 /* 749 * Copy down exception vector code. 750 */ 751 if (mips1_utlb_miss_end - mips1_utlb_miss > 0x80) 752 panic("startup: UTLB vector code too large"); 753 if (mips1_exception_end - mips1_exception > 0x80) 754 panic("startup: general exception vector code too large"); 755 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips1_utlb_miss, 756 mips1_exception_end - mips1_utlb_miss); 757 758 /* 759 * Copy locore-function vector. 760 */ 761 mips_locore_jumpvec = mips1_locore_vec; 762 763 /* 764 * Clear out the I and D caches. 765 */ 766 mips_icache_sync_all(); 767 mips_dcache_wbinv_all(); 768 } 769 #endif /* MIPS1 */ 770 771 #if defined(MIPS3) 772 static void 773 mips3_vector_init(const struct splsw *splsw) 774 { 775 /* r4000 exception handler address and end */ 776 extern char mips3_exception[], mips3_exception_end[]; 777 778 /* TLB miss handler address and end */ 779 extern char mips3_tlb_miss[]; 780 extern char mips3_xtlb_miss[]; 781 782 /* Cache error handler */ 783 extern char mips3_cache[]; 784 /* 785 * Copy down exception vector code. 786 */ 787 788 if (mips3_xtlb_miss - mips3_tlb_miss != 0x80) 789 panic("startup: %s vector code not 128 bytes in length", 790 "UTLB"); 791 if (mips3_cache - mips3_xtlb_miss != 0x80) 792 panic("startup: %s vector code not 128 bytes in length", 793 "XTLB"); 794 if (mips3_exception - mips3_cache != 0x80) 795 panic("startup: %s vector code not 128 bytes in length", 796 "Cache error"); 797 if (mips3_exception_end - mips3_exception > 0x80) 798 panic("startup: %s vector code too large", 799 "General exception"); 800 801 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips3_tlb_miss, 802 mips3_exception_end - mips3_tlb_miss); 803 804 /* 805 * Copy locore-function vector. 806 */ 807 mips_locore_jumpvec = mips3_locore_vec; 808 809 mips_icache_sync_all(); 810 mips_dcache_wbinv_all(); 811 812 /* Clear BEV in SR so we start handling our own exceptions */ 813 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 814 } 815 #endif /* MIPS3 */ 816 817 #if defined(MIPS3_LOONGSON2) 818 static void 819 loongson2_vector_init(const struct splsw *splsw) 820 { 821 /* r4000 exception handler address and end */ 822 extern char loongson2_exception[], loongson2_exception_end[]; 823 824 /* TLB miss handler address and end */ 825 extern char loongson2_tlb_miss[]; 826 extern char loongson2_xtlb_miss[]; 827 828 /* Cache error handler */ 829 extern char loongson2_cache[]; 830 831 /* 832 * Copy down exception vector code. 833 */ 834 835 if (loongson2_xtlb_miss - loongson2_tlb_miss != 0x80) 836 panic("startup: %s vector code not 128 bytes in length", 837 "UTLB"); 838 if (loongson2_cache - loongson2_xtlb_miss != 0x80) 839 panic("startup: %s vector code not 128 bytes in length", 840 "XTLB"); 841 if (loongson2_exception - loongson2_cache != 0x80) 842 panic("startup: %s vector code not 128 bytes in length", 843 "Cache error"); 844 if (loongson2_exception_end - loongson2_exception > 0x80) 845 panic("startup: %s vector code too large", 846 "General exception"); 847 848 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, loongson2_tlb_miss, 849 loongson2_exception_end - loongson2_tlb_miss); 850 851 /* 852 * Copy locore-function vector. 853 */ 854 mips_locore_jumpvec = loongson2_locore_vec; 855 856 mips_icache_sync_all(); 857 mips_dcache_wbinv_all(); 858 859 /* Clear BEV in SR so we start handling our own exceptions */ 860 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 861 } 862 #endif /* MIPS3_LOONGSON2 */ 863 864 #if defined(MIPS32) 865 static void 866 mips32_vector_init(const struct splsw *splsw) 867 { 868 /* r4000 exception handler address */ 869 extern char mips32_exception[]; 870 871 /* TLB miss handler addresses */ 872 extern char mips32_tlb_miss[]; 873 874 /* Cache error handler */ 875 extern char mips32_cache[]; 876 877 /* MIPS32 interrupt exception handler */ 878 extern char mips32_intr[], mips32_intr_end[]; 879 880 /* 881 * Copy down exception vector code. 882 */ 883 884 if (mips32_cache - mips32_tlb_miss != 0x100) 885 panic("startup: %s vector code not 128 bytes in length", 886 "UTLB"); 887 if (mips32_exception - mips32_cache != 0x80) 888 panic("startup: %s vector code not 128 bytes in length", 889 "Cache error"); 890 if (mips32_intr - mips32_exception != 0x80) 891 panic("startup: %s vector code not 128 bytes in length", 892 "General exception"); 893 if (mips32_intr_end - mips32_intr > 0x80) 894 panic("startup: %s vector code too large", 895 "interrupt exception"); 896 897 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32_tlb_miss, 898 mips32_intr_end - mips32_tlb_miss); 899 900 /* 901 * Copy locore-function vector. 902 */ 903 mips_locore_jumpvec = mips32_locore_vec; 904 905 mips_icache_sync_all(); 906 mips_dcache_wbinv_all(); 907 908 /* Clear BEV in SR so we start handling our own exceptions */ 909 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 910 911 mips_watchpoint_init(); 912 } 913 #endif /* MIPS32 */ 914 915 #if defined(MIPS32R2) 916 static void 917 mips32r2_vector_init(const struct splsw *splsw) 918 { 919 /* r4000 exception handler address */ 920 extern char mips32r2_exception[]; 921 922 /* TLB miss handler addresses */ 923 extern char mips32r2_tlb_miss[]; 924 925 /* Cache error handler */ 926 extern char mips32r2_cache[]; 927 928 /* MIPS32 interrupt exception handler */ 929 extern char mips32r2_intr[], mips32r2_intr_end[]; 930 931 /* 932 * Copy down exception vector code. 933 */ 934 if (mips32r2_cache - mips32r2_tlb_miss != 0x100) 935 panic("startup: %s vector code not 128 bytes in length", 936 "UTLB"); 937 if (mips32r2_exception - mips32r2_cache != 0x80) 938 panic("startup: %s vector code not 128 bytes in length", 939 "Cache error"); 940 if (mips32r2_intr - mips32r2_exception != 0x80) 941 panic("startup: %s vector code not 128 bytes in length", 942 "General exception"); 943 if (mips32r2_intr_end - mips32r2_intr > 0x80) 944 panic("startup: %s vector code too large", 945 "interrupt exception"); 946 947 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32r2_tlb_miss, 948 mips32r2_intr_end - mips32r2_tlb_miss); 949 950 /* 951 * Let's see if this cpu has USERLOCAL or DSP V2 ASE... 952 */ 953 if (mipsNN_cp0_config2_read() & MIPSNN_CFG2_M) { 954 const uint32_t cfg3 = mipsNN_cp0_config3_read(); 955 if (cfg3 & MIPSNN_CFG3_ULRI) { 956 mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_USERLOCAL; 957 } 958 if (cfg3 & MIPSNN_CFG3_DSP2P) { 959 mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_DSP; 960 } 961 } 962 963 /* 964 * If this CPU doesn't have a COP0 USERLOCAL register, at the end 965 * of cpu_switch resume overwrite the instructions which update it. 966 */ 967 if (!MIPS_HAS_USERLOCAL) { 968 extern uint32_t mips32r2_cpu_switch_resume[]; 969 for (uint32_t *insnp = mips32r2_cpu_switch_resume;; insnp++) { 970 KASSERT(insnp[0] != JR_RA); 971 if (insnp[0] == _LOAD_V0_L_PRIVATE_A0 972 && insnp[1] == _MTC0_V0_USERLOCAL) { 973 insnp[0] = JR_RA; 974 insnp[1] = 0; /* NOP */ 975 break; 976 } 977 } 978 } 979 980 /* 981 * Copy locore-function vector. 982 */ 983 mips_locore_jumpvec = mips32r2_locore_vec; 984 985 mips_icache_sync_all(); 986 mips_dcache_wbinv_all(); 987 988 /* Clear BEV in SR so we start handling our own exceptions */ 989 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 990 991 mips_watchpoint_init(); 992 } 993 #endif /* MIPS32R2 */ 994 995 #if defined(MIPS64) 996 static void 997 mips64_vector_init(const struct splsw *splsw) 998 { 999 /* r4000 exception handler address */ 1000 extern char mips64_exception[]; 1001 1002 /* TLB miss handler addresses */ 1003 extern char mips64_tlb_miss[]; 1004 extern char mips64_xtlb_miss[]; 1005 1006 /* Cache error handler */ 1007 extern char mips64_cache[]; 1008 1009 /* MIPS64 interrupt exception handler */ 1010 extern char mips64_intr[], mips64_intr_end[]; 1011 1012 /* 1013 * Copy down exception vector code. 1014 */ 1015 1016 if (mips64_xtlb_miss - mips64_tlb_miss != 0x80) 1017 panic("startup: %s vector code not 128 bytes in length", 1018 "UTLB"); 1019 if (mips64_cache - mips64_xtlb_miss != 0x80) 1020 panic("startup: %s vector code not 128 bytes in length", 1021 "XTLB"); 1022 if (mips64_exception - mips64_cache != 0x80) 1023 panic("startup: %s vector code not 128 bytes in length", 1024 "Cache error"); 1025 if (mips64_intr - mips64_exception != 0x80) 1026 panic("startup: %s vector code not 128 bytes in length", 1027 "General exception"); 1028 if (mips64_intr_end - mips64_intr > 0x80) 1029 panic("startup: %s vector code too large", 1030 "interrupt exception"); 1031 1032 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips64_tlb_miss, 1033 mips64_intr_end - mips64_tlb_miss); 1034 1035 /* 1036 * Copy locore-function vector. 1037 */ 1038 mips_locore_jumpvec = mips64_locore_vec; 1039 1040 mips_icache_sync_all(); 1041 mips_dcache_wbinv_all(); 1042 1043 /* Clear BEV in SR so we start handling our own exceptions */ 1044 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 1045 1046 mips_watchpoint_init(); 1047 } 1048 #endif /* MIPS64 */ 1049 1050 #if defined(MIPS64R2) 1051 void 1052 mips64r2_vector_init(const struct splsw *splsw) 1053 { 1054 /* r4000 exception handler address */ 1055 extern char mips64r2_exception[]; 1056 1057 /* TLB miss handler addresses */ 1058 extern char mips64r2_tlb_miss[]; 1059 extern char mips64r2_xtlb_miss[]; 1060 1061 /* Cache error handler */ 1062 extern char mips64r2_cache[]; 1063 1064 /* MIPS64 interrupt exception handler */ 1065 extern char mips64r2_intr[], mips64r2_intr_end[]; 1066 1067 /* 1068 * Copy down exception vector code. 1069 */ 1070 1071 if (mips64r2_xtlb_miss - mips64r2_tlb_miss != 0x80) 1072 panic("startup: %s vector code not 128 bytes in length", 1073 "UTLB"); 1074 if (mips64r2_cache - mips64r2_xtlb_miss != 0x80) 1075 panic("startup: %s vector code not 128 bytes in length", 1076 "XTLB"); 1077 if (mips64r2_exception - mips64r2_cache != 0x80) 1078 panic("startup: %s vector code not 128 bytes in length", 1079 "Cache error"); 1080 if (mips64r2_intr - mips64r2_exception != 0x80) 1081 panic("startup: %s vector code not 128 bytes in length", 1082 "General exception"); 1083 if (mips64r2_intr_end - mips64r2_intr > 0x80) 1084 panic("startup: %s vector code too large", 1085 "interrupt exception"); 1086 1087 const intptr_t ebase = (intptr_t)mipsNN_cp0_ebase_read(); 1088 const int cpunum = ebase & MIPS_EBASE_CPUNUM; 1089 1090 // This may need to be on CPUs other CPU0 so use EBASE to fetch 1091 // the appropriate address for exception code. EBASE also contains 1092 // the cpunum so remove that. 1093 memcpy((void *)(intptr_t)(ebase & ~MIPS_EBASE_CPUNUM), mips64r2_tlb_miss, 1094 mips64r2_intr_end - mips64r2_tlb_miss); 1095 1096 /* 1097 * Let's see if this cpu has USERLOCAL or DSP V2 ASE... 1098 */ 1099 if (mipsNN_cp0_config2_read() & MIPSNN_CFG2_M) { 1100 const uint32_t cfg3 = mipsNN_cp0_config3_read(); 1101 if (cfg3 & MIPSNN_CFG3_ULRI) { 1102 mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_USERLOCAL; 1103 } 1104 if (cfg3 & MIPSNN_CFG3_DSP2P) { 1105 mips_options.mips_cpu_flags |= CPU_MIPS_HAVE_DSP; 1106 } 1107 } 1108 1109 /* 1110 * If this CPU doesn't have a COP0 USERLOCAL register, at the end 1111 * of cpu_switch resume overwrite the instructions which update it. 1112 */ 1113 if (!MIPS_HAS_USERLOCAL && cpunum == 0) { 1114 extern uint32_t mips64r2_cpu_switch_resume[]; 1115 for (uint32_t *insnp = mips64r2_cpu_switch_resume;; insnp++) { 1116 KASSERT(insnp[0] != JR_RA); 1117 if (insnp[0] == _LOAD_V0_L_PRIVATE_A0 1118 && insnp[1] == _MTC0_V0_USERLOCAL) { 1119 insnp[0] = JR_RA; 1120 insnp[1] = 0; /* NOP */ 1121 break; 1122 } 1123 } 1124 } 1125 1126 /* 1127 * Copy locore-function vector. 1128 */ 1129 if (cpunum == 0) 1130 mips_locore_jumpvec = mips64r2_locore_vec; 1131 1132 mips_icache_sync_all(); 1133 mips_dcache_wbinv_all(); 1134 1135 /* Clear BEV in SR so we start handling our own exceptions */ 1136 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS_SR_BEV); 1137 1138 mips_watchpoint_init(); 1139 } 1140 #endif /* MIPS64R2 */ 1141 1142 /* 1143 * Do all the stuff that locore normally does before calling main(), 1144 * that is common to all mips-CPU NetBSD ports. 1145 * 1146 * The principal purpose of this function is to examine the 1147 * variable cpu_id, into which the kernel locore start code 1148 * writes the CPU ID register, and to then copy appropriate 1149 * code into the CPU exception-vector entries and the jump tables 1150 * used to hide the differences in cache and TLB handling in 1151 * different MIPS CPUs. 1152 * 1153 * This should be the very first thing called by each port's 1154 * init_main() function. 1155 */ 1156 1157 /* 1158 * Initialize the hardware exception vectors, and the jump table used to 1159 * call locore cache and TLB management functions, based on the kind 1160 * of CPU the kernel is running on. 1161 */ 1162 void 1163 mips_vector_init(const struct splsw *splsw, bool multicpu_p) 1164 { 1165 struct mips_options * const opts = &mips_options; 1166 const struct pridtab *ct; 1167 const mips_prid_t cpu_id = opts->mips_cpu_id; 1168 1169 for (ct = cputab; ct->cpu_name != NULL; ct++) { 1170 if (MIPS_PRID_CID(cpu_id) != ct->cpu_cid || 1171 MIPS_PRID_IMPL(cpu_id) != ct->cpu_pid) 1172 continue; 1173 if (ct->cpu_rev >= 0 && 1174 MIPS_PRID_REV(cpu_id) != ct->cpu_rev) 1175 continue; 1176 if (ct->cpu_copts >= 0 && 1177 MIPS_PRID_COPTS(cpu_id) != ct->cpu_copts) 1178 continue; 1179 1180 opts->mips_cpu = ct; 1181 opts->mips_cpu_arch = ct->cpu_isa; 1182 opts->mips_num_tlb_entries = ct->cpu_ntlb; 1183 break; 1184 } 1185 1186 if (opts->mips_cpu == NULL) 1187 panic("CPU type (0x%x) not supported", cpu_id); 1188 1189 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 1190 if (MIPS_PRID_CID(cpu_id) != 0) { 1191 /* MIPS32/MIPS64, use coprocessor 0 config registers */ 1192 uint32_t cfg, cfg1, cfg4; 1193 1194 cfg = mips3_cp0_config_read(); 1195 cfg1 = mipsNN_cp0_config1_read(); 1196 if (opts->mips_cpu->cpu_cp0flags & MIPS_CP0FL_CONFIG4) 1197 cfg4 = mipsNN_cp0_config4_read(); 1198 else 1199 cfg4 = 0; 1200 1201 /* pick CPU type */ 1202 switch (MIPSNN_GET(CFG_AT, cfg)) { 1203 case MIPSNN_CFG_AT_MIPS32: 1204 opts->mips_cpu_arch = CPU_ARCH_MIPS32; 1205 break; 1206 case MIPSNN_CFG_AT_MIPS64: 1207 opts->mips_cpu_arch = CPU_ARCH_MIPS64; 1208 break; 1209 case MIPSNN_CFG_AT_MIPS64S: 1210 default: 1211 panic("MIPS32/64 architecture type %d not supported", 1212 MIPSNN_GET(CFG_AT, cfg)); 1213 } 1214 1215 switch (MIPSNN_GET(CFG_AR, cfg)) { 1216 case MIPSNN_CFG_AR_REV1: 1217 break; 1218 case MIPSNN_CFG_AR_REV2: 1219 switch (opts->mips_cpu_arch) { 1220 case CPU_ARCH_MIPS32: 1221 opts->mips_cpu_arch = CPU_ARCH_MIPS32R2; 1222 break; 1223 case CPU_ARCH_MIPS64: 1224 opts->mips_cpu_arch = CPU_ARCH_MIPS64R2; 1225 break; 1226 default: 1227 printf("WARNING: MIPS32/64 arch %d revision %d " 1228 "unknown!\n", opts->mips_cpu_arch, 1229 MIPSNN_GET(CFG_AR, cfg)); 1230 break; 1231 } 1232 break; 1233 default: 1234 printf("WARNING: MIPS32/64 arch revision %d " 1235 "unknown!\n", MIPSNN_GET(CFG_AR, cfg)); 1236 break; 1237 } 1238 1239 /* figure out MMU type (and number of TLB entries) */ 1240 switch (MIPSNN_GET(CFG_MT, cfg)) { 1241 case MIPSNN_CFG_MT_TLB: 1242 /* 1243 * Config1[MMUSize-1] defines the number of TLB 1244 * entries minus 1, allowing up to 64 TLBs to be 1245 * defined. For MIPS32R2 and MIPS64R2 and later 1246 * if the Config4[MMUExtDef] field is 1 then the 1247 * Config4[MMUSizeExt] field is an extension of 1248 * Config1[MMUSize-1] field. 1249 */ 1250 opts->mips_num_tlb_entries = MIPSNN_CFG1_MS(cfg1); 1251 if (__SHIFTOUT(cfg4, MIPSNN_CFG4_MMU_EXT_DEF) == 1252 MIPSNN_CFG4_MMU_EXT_DEF_MMU) { 1253 opts->mips_num_tlb_entries += 1254 __SHIFTOUT(cfg4, MIPSNN_CFG4_MMU_SIZE_EXT) << 1255 popcount(MIPSNN_CFG1_MS_MASK); 1256 } 1257 break; 1258 case MIPSNN_CFG_MT_NONE: 1259 case MIPSNN_CFG_MT_BAT: 1260 case MIPSNN_CFG_MT_FIXED: 1261 default: 1262 panic("MIPS32/64 MMU type %d not supported", 1263 MIPSNN_GET(CFG_MT, cfg)); 1264 } 1265 } 1266 #endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */ 1267 1268 if (opts->mips_cpu_arch < 1) 1269 panic("Unknown CPU ISA for CPU type 0x%x", cpu_id); 1270 if (opts->mips_num_tlb_entries < 1) 1271 panic("Unknown number of TLBs for CPU type 0x%x", cpu_id); 1272 1273 /* 1274 * Check CPU-specific flags. 1275 */ 1276 opts->mips_cpu_flags = opts->mips_cpu->cpu_flags; 1277 opts->mips_has_r4k_mmu = (opts->mips_cpu_flags & CPU_MIPS_R4K_MMU) != 0; 1278 opts->mips_has_llsc = (opts->mips_cpu_flags & CPU_MIPS_NO_LLSC) == 0; 1279 #if defined(MIPS3_4100) 1280 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100) 1281 opts->mips3_pg_shift = MIPS3_4100_PG_SHIFT; 1282 else 1283 #endif 1284 opts->mips3_pg_shift = MIPS3_DEFAULT_PG_SHIFT; 1285 1286 opts->mips3_cca_devmem = CCA_UNCACHED; 1287 if (opts->mips_cpu_flags & CPU_MIPS_HAVE_SPECIAL_CCA) { 1288 uint32_t cca; 1289 1290 cca = (opts->mips_cpu_flags & CPU_MIPS_CACHED_CCA_MASK) >> 1291 CPU_MIPS_CACHED_CCA_SHIFT; 1292 opts->mips3_pg_cached = MIPS3_CCA_TO_PG(cca); 1293 #ifndef __mips_o32 1294 opts->mips3_xkphys_cached = MIPS_PHYS_TO_XKPHYS(cca, 0); 1295 #endif 1296 } else { 1297 opts->mips3_pg_cached = MIPS3_DEFAULT_PG_CACHED; 1298 #ifndef __mips_o32 1299 opts->mips3_xkphys_cached = MIPS3_DEFAULT_XKPHYS_CACHED; 1300 #endif 1301 } 1302 1303 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG 1304 mips_machdep_cache_config(); 1305 #endif 1306 1307 /* 1308 * if 'splsw' is NULL, use standard SPL with COP0 status/cause 1309 * otherwise use chip-specific splsw 1310 */ 1311 if (splsw == NULL) { 1312 mips_splsw = std_splsw; 1313 #ifdef PARANOIA 1314 std_splsw_test(); /* only works with std_splsw */ 1315 #endif 1316 } else { 1317 mips_splsw = *splsw; 1318 } 1319 1320 /* 1321 * Determine cache configuration and initialize our cache 1322 * frobbing routine function pointers. 1323 */ 1324 mips_config_cache(); 1325 1326 /* 1327 * We default to RAS atomic ops since they are the lowest overhead. 1328 */ 1329 #ifdef MULTIPROCESSOR 1330 if (multicpu_p) { 1331 /* 1332 * If we could have multiple CPUs active, 1333 * use the ll/sc variants. 1334 */ 1335 mips_locore_atomicvec = mips_llsc_locore_atomicvec; 1336 } 1337 #endif 1338 /* 1339 * Now initialize our ISA-dependent function vector. 1340 */ 1341 switch (opts->mips_cpu_arch) { 1342 #if defined(MIPS1) 1343 case CPU_ARCH_MIPS1: 1344 (*mips1_locore_vec.ljv_tlb_invalidate_all)(); 1345 mips1_vector_init(splsw); 1346 mips_locoresw = mips1_locoresw; 1347 break; 1348 #endif 1349 #if defined(MIPS3) 1350 case CPU_ARCH_MIPS3: 1351 case CPU_ARCH_MIPS4: 1352 mips3_tlb_probe(); 1353 #if defined(MIPS3_4100) 1354 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100) 1355 mips3_cp0_pg_mask_write(MIPS4100_PG_SIZE_TO_MASK(PAGE_SIZE)); 1356 else 1357 #endif 1358 mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); 1359 mips3_cp0_wired_write(0); 1360 #if defined(MIPS3_LOONGSON2) 1361 if (opts->mips_cpu_flags & CPU_MIPS_LOONGSON2) { 1362 (*loongson2_locore_vec.ljv_tlb_invalidate_all)(); 1363 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1364 loongson2_vector_init(splsw); 1365 mips_locoresw = loongson2_locoresw; 1366 opts->mips3_cca_devmem = CCA_ACCEL; 1367 break; 1368 } 1369 #endif /* MIPS3_LOONGSON2 */ 1370 (*mips3_locore_vec.ljv_tlb_invalidate_all)(); 1371 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1372 mips3_vector_init(splsw); 1373 mips_locoresw = mips3_locoresw; 1374 break; 1375 1376 #endif /* MIPS3 */ 1377 #if defined(MIPS32) 1378 case CPU_ARCH_MIPS32: 1379 mips3_tlb_probe(); 1380 mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); 1381 mips3_cp0_wired_write(0); 1382 (*mips32_locore_vec.ljv_tlb_invalidate_all)(); 1383 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1384 mips32_vector_init(splsw); 1385 mips_locoresw = mips32_locoresw; 1386 break; 1387 #endif 1388 #if defined(MIPS32R2) 1389 case CPU_ARCH_MIPS32R2: 1390 mips3_tlb_probe(); 1391 mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); 1392 mips3_cp0_wired_write(0); 1393 (*mips32r2_locore_vec.ljv_tlb_invalidate_all)(); 1394 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1395 mips32r2_vector_init(splsw); 1396 mips_locoresw = mips32r2_locoresw; 1397 break; 1398 #endif 1399 #if defined(MIPS64) 1400 case CPU_ARCH_MIPS64: { 1401 mips3_tlb_probe(); 1402 mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); 1403 mips3_cp0_wired_write(0); 1404 (*mips64_locore_vec.ljv_tlb_invalidate_all)(); 1405 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1406 mips64_vector_init(splsw); 1407 mips_locoresw = mips64_locoresw; 1408 break; 1409 } 1410 #endif 1411 #if defined(MIPS64R2) 1412 case CPU_ARCH_MIPS64R2: { 1413 mips3_tlb_probe(); 1414 mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_TO_MASK(PAGE_SIZE)); 1415 mips3_cp0_wired_write(0); 1416 (*mips64r2_locore_vec.ljv_tlb_invalidate_all)(); 1417 mips3_cp0_wired_write(pmap_tlb0_info.ti_wired); 1418 mips64r2_vector_init(splsw); 1419 mips_locoresw = mips64r2_locoresw; 1420 break; 1421 } 1422 #endif 1423 default: 1424 printf("cpu_arch 0x%x: not supported\n", opts->mips_cpu_arch); 1425 cpu_reboot(RB_HALT, NULL); 1426 } 1427 1428 /* 1429 * Now that the splsw and locoresw have been filled in, fixup the 1430 * jumps to any stubs to actually jump to the real routines. 1431 */ 1432 extern uint32_t _ftext[]; 1433 extern uint32_t _etext[]; 1434 mips_fixup_stubs(_ftext, _etext); 1435 1436 #if (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 1437 /* 1438 * Install power-saving idle routines. 1439 */ 1440 if ((opts->mips_cpu_flags & CPU_MIPS_USE_WAIT) && 1441 !(opts->mips_cpu_flags & CPU_MIPS_NO_WAIT)) 1442 mips_locoresw.lsw_cpu_idle = mips_wait_idle; 1443 #endif /* (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */ 1444 } 1445 1446 void 1447 mips_set_wbflush(void (*flush_fn)(void)) 1448 { 1449 mips_locoresw.lsw_wbflush = flush_fn; 1450 (*flush_fn)(); 1451 } 1452 1453 #if defined(MIPS3_PLUS) 1454 static void 1455 mips3_tlb_probe(void) 1456 { 1457 struct mips_options * const opts = &mips_options; 1458 opts->mips3_tlb_pg_mask = mips3_cp0_tlb_page_mask_probe(); 1459 if (CPUIS64BITS) { 1460 opts->mips3_tlb_vpn_mask = mips3_cp0_tlb_entry_hi_probe(); 1461 opts->mips3_tlb_vpn_mask |= PAGE_MASK; 1462 opts->mips3_tlb_vpn_mask <<= 2; 1463 opts->mips3_tlb_vpn_mask >>= 2; 1464 opts->mips3_tlb_pfn_mask = mips3_cp0_tlb_entry_lo_probe(); 1465 #if defined(_LP64) && defined(ENABLE_MIPS_16KB_PAGE) 1466 /* 1467 * 16KB pages could cause our page table being able to address 1468 * a larger address space than the actual chip supports. So 1469 * we need to limit the address space to what it can really 1470 * address. 1471 */ 1472 if (mips_vm_maxuser_address > opts->mips3_tlb_vpn_mask + 1) 1473 mips_vm_maxuser_address = opts->mips3_tlb_vpn_mask + 1; 1474 #endif 1475 } 1476 } 1477 #endif 1478 1479 static const char * 1480 wayname(int ways) 1481 { 1482 static char buf[sizeof("xxx-way set-associative")]; 1483 1484 #ifdef DIAGNOSTIC 1485 if (ways > 999) 1486 panic("mips cache - too many ways (%d)", ways); 1487 #endif 1488 1489 switch (ways) { 1490 case 0: 1491 return "fully set-associative"; 1492 case 1: 1493 return "direct-mapped"; 1494 default: 1495 snprintf(buf, sizeof(buf), "%d-way set-associative", ways); 1496 return buf; 1497 } 1498 } 1499 1500 /* 1501 * Identify product revision IDs of CPU and FPU. 1502 */ 1503 void 1504 cpu_identify(device_t dev) 1505 { 1506 const struct mips_options * const opts = &mips_options; 1507 const struct mips_cache_info * const mci = &mips_cache_info; 1508 const mips_prid_t cpu_id = opts->mips_cpu_id; 1509 const mips_prid_t fpu_id = opts->mips_fpu_id; 1510 static const char * const wtnames[] = { 1511 "write-back", 1512 "write-through", 1513 }; 1514 const char *cpuname, *fpuname; 1515 int i; 1516 1517 cpuname = opts->mips_cpu->cpu_name; 1518 #ifdef MIPS64_OCTEON 1519 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_CAVIUM) { 1520 cpuname = octeon_cpu_model(cpu_id); 1521 } 1522 #endif 1523 1524 fpuname = NULL; 1525 for (i = 0; i < sizeof(fputab)/sizeof(fputab[0]); i++) { 1526 if (MIPS_PRID_CID(fpu_id) == fputab[i].cpu_cid && 1527 MIPS_PRID_IMPL(fpu_id) == fputab[i].cpu_pid) { 1528 fpuname = fputab[i].cpu_name; 1529 break; 1530 } 1531 } 1532 if (fpuname == NULL && MIPS_PRID_IMPL(fpu_id) == MIPS_PRID_IMPL(cpu_id)) 1533 fpuname = "built-in FPU"; 1534 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4700) /* FPU PRid is 0x20 */ 1535 fpuname = "built-in FPU"; 1536 if (MIPS_PRID_IMPL(cpu_id) == MIPS_RC64470) /* FPU PRid is 0x21 */ 1537 fpuname = "built-in FPU"; 1538 #ifdef MIPSNN 1539 if (CPUISMIPSNN) { 1540 uint32_t cfg1; 1541 1542 switch (MIPS_PRID_CID(cpu_id)) { 1543 /* 1544 * CPUs from the following companies have a built-in 1545 * FPU if Config1[FP] is set. 1546 */ 1547 case MIPS_PRID_CID_SIBYTE: 1548 case MIPS_PRID_CID_CAVIUM: 1549 cfg1 = mipsNN_cp0_config1_read(); 1550 if (cfg1 & MIPSNN_CFG1_FP) 1551 fpuname = "built-in FPU"; 1552 break; 1553 } 1554 } 1555 #endif 1556 1557 if (opts->mips_cpu->cpu_cid != 0) { 1558 if (opts->mips_cpu->cpu_cid <= ncidnames) 1559 aprint_normal("%s ", cidnames[opts->mips_cpu->cpu_cid]); 1560 else if (opts->mips_cpu->cpu_cid == MIPS_PRID_CID_INGENIC) { 1561 aprint_normal("Ingenic "); 1562 } else { 1563 aprint_normal("Unknown Company ID - 0x%x", 1564 opts->mips_cpu->cpu_cid); 1565 aprint_normal_dev(dev, ""); 1566 } 1567 } 1568 if (cpuname != NULL) 1569 aprint_normal("%s (0x%x)", cpuname, cpu_id); 1570 else 1571 aprint_normal("unknown CPU type (0x%x)", cpu_id); 1572 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) 1573 aprint_normal(" Rev. %d.%d", MIPS_PRID_REV_MAJ(cpu_id), 1574 MIPS_PRID_REV_MIN(cpu_id)); 1575 else 1576 aprint_normal(" Rev. %d", MIPS_PRID_REV(cpu_id)); 1577 1578 if (fpuname != NULL) 1579 aprint_normal(" with %s", fpuname); 1580 else 1581 aprint_normal(" with unknown FPC type (0x%x)", fpu_id); 1582 if (opts->mips_fpu_id != 0) { 1583 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) 1584 aprint_normal(" Rev. %d.%d", MIPS_PRID_REV_MAJ(fpu_id), 1585 MIPS_PRID_REV_MIN(fpu_id)); 1586 else 1587 aprint_normal(" Rev. %d", MIPS_PRID_REV(fpu_id)); 1588 } 1589 if (opts->mips_cpu_flags & MIPS_HAS_DSP) { 1590 aprint_normal(" and DSPv2"); 1591 } 1592 aprint_normal("\n"); 1593 1594 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC && 1595 MIPS_PRID_RSVD(cpu_id) != 0) { 1596 aprint_normal_dev(dev, 1597 "NOTE: top 8 bits of prehistoric PRID not 0!\n"); 1598 aprint_normal_dev(dev, "Please mail port-mips (at) NetBSD.org " 1599 "with %s dmesg lines.\n", device_xname(dev)); 1600 } 1601 1602 switch (opts->mips_cpu_arch) { 1603 #if defined(MIPS1) 1604 case CPU_ARCH_MIPS1: 1605 if (mci->mci_picache_size) 1606 aprint_normal_dev(dev, "%dKB/%dB %s Instruction cache, " 1607 "%d TLB entries\n", mci->mci_picache_size / 1024, 1608 mci->mci_picache_line_size, 1609 wayname(mci->mci_picache_ways), 1610 opts->mips_num_tlb_entries); 1611 else 1612 aprint_normal_dev(dev, "%d TLB entries\n", 1613 opts->mips_num_tlb_entries); 1614 if (mci->mci_pdcache_size) 1615 aprint_normal_dev(dev, "%dKB/%dB %s %s Data cache\n", 1616 mci->mci_pdcache_size / 1024, 1617 mci->mci_pdcache_line_size, 1618 wayname(mci->mci_pdcache_ways), 1619 wtnames[mci->mci_pdcache_write_through]); 1620 break; 1621 #endif /* MIPS1 */ 1622 #if (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 1623 case CPU_ARCH_MIPS3: 1624 case CPU_ARCH_MIPS4: 1625 case CPU_ARCH_MIPS32: 1626 case CPU_ARCH_MIPS32R2: 1627 case CPU_ARCH_MIPS64: 1628 case CPU_ARCH_MIPS64R2: { 1629 const char *sufx = "KMGTPE"; 1630 uint32_t pg_mask; 1631 aprint_normal_dev(dev, "%d TLB entries", 1632 opts->mips_num_tlb_entries); 1633 #if !defined(__mips_o32) 1634 if (CPUIS64BITS) { 1635 int64_t pfn_mask; 1636 i = ffs(~(opts->mips3_tlb_vpn_mask >> 31)) + 30; 1637 aprint_normal(", %d%cB (%d-bit) VAs", 1638 1 << (i % 10), sufx[(i / 10) - 1], i); 1639 for (i = 64, pfn_mask = opts->mips3_tlb_pfn_mask << 6; 1640 pfn_mask > 0; i--, pfn_mask <<= 1) 1641 ; 1642 aprint_normal(", %d%cB (%d-bit) PAs", 1643 1 << (i % 10), sufx[(i / 10) - 1], i); 1644 } 1645 #endif 1646 for (i = 4, pg_mask = opts->mips3_tlb_pg_mask >> 13; 1647 pg_mask != 0; ) { 1648 if ((pg_mask & 3) != 3) 1649 break; 1650 pg_mask >>= 2; 1651 i *= 4; 1652 if (i == 1024) { 1653 i = 1; 1654 sufx++; 1655 } 1656 } 1657 aprint_normal(", %d%cB max page size\n", i, sufx[0]); 1658 if (mci->mci_picache_size) 1659 aprint_normal_dev(dev, 1660 "%dKB/%dB %s L1 instruction cache\n", 1661 mci->mci_picache_size / 1024, 1662 mci->mci_picache_line_size, 1663 wayname(mci->mci_picache_ways)); 1664 if (mci->mci_pdcache_size) 1665 aprint_normal_dev(dev, 1666 "%dKB/%dB %s %s %sL1 data cache\n", 1667 mci->mci_pdcache_size / 1024, 1668 mci->mci_pdcache_line_size, 1669 wayname(mci->mci_pdcache_ways), 1670 wtnames[mci->mci_pdcache_write_through], 1671 ((opts->mips_cpu_flags & CPU_MIPS_D_CACHE_COHERENT) 1672 ? "coherent " : "")); 1673 if (mci->mci_sdcache_line_size) 1674 aprint_normal_dev(dev, 1675 "%dKB/%dB %s %s L2 %s cache\n", 1676 mci->mci_sdcache_size / 1024, 1677 mci->mci_sdcache_line_size, 1678 wayname(mci->mci_sdcache_ways), 1679 wtnames[mci->mci_sdcache_write_through], 1680 mci->mci_scache_unified ? "unified" : "data"); 1681 break; 1682 } 1683 #endif /* (MIPS3 + MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */ 1684 default: 1685 panic("cpu_identify: impossible"); 1686 } 1687 } 1688 1689 /* 1690 * Set registers on exec. 1691 * Clear all registers except sp, pc, and t9. 1692 * $sp is set to the stack pointer passed in. $pc is set to the entry 1693 * point given by the exec_package passed in, as is $t9 (used for PIC 1694 * code by the MIPS elf abi). 1695 */ 1696 void 1697 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 1698 { 1699 struct trapframe * const tf = l->l_md.md_utf; 1700 struct proc * const p = l->l_proc; 1701 1702 KASSERTMSG((stack & STACK_ALIGNBYTES) == 0, "stack=%"PRIxVADDR, stack); 1703 1704 memset(tf, 0, sizeof(*tf)); 1705 tf->tf_regs[_R_SP] = (intptr_t)stack & ~STACK_ALIGNBYTES; 1706 tf->tf_regs[_R_PC] = (intptr_t)pack->ep_entry & ~3; 1707 tf->tf_regs[_R_T9] = (intptr_t)pack->ep_entry & ~3; /* abicall requirement */ 1708 tf->tf_regs[_R_SR] = PSL_USERSET; 1709 #if !defined(__mips_o32) 1710 /* 1711 * allow 64bit ops in userland for non-O32 ABIs 1712 */ 1713 if (p->p_md.md_abi == _MIPS_BSD_API_N32 1714 && (CPUISMIPS64 || CPUISMIPS64R2)) { 1715 tf->tf_regs[_R_SR] |= MIPS_SR_PX; 1716 } else if (p->p_md.md_abi != _MIPS_BSD_API_O32) { 1717 tf->tf_regs[_R_SR] |= MIPS_SR_UX; 1718 } 1719 if (_MIPS_SIM_NEWABI_P(p->p_md.md_abi)) 1720 tf->tf_regs[_R_SR] |= MIPS3_SR_FR; 1721 #endif 1722 #ifdef _LP64 1723 /* 1724 * If we are using a 32-bit ABI on a 64-bit kernel, mark the process 1725 * that way. If we aren't, clear it. 1726 */ 1727 if (p->p_md.md_abi == _MIPS_BSD_API_N32 1728 || p->p_md.md_abi == _MIPS_BSD_API_O32) { 1729 p->p_flag |= PK_32; 1730 } else { 1731 p->p_flag &= ~PK_32; 1732 } 1733 #endif 1734 /* 1735 * Set up arguments for _start(): 1736 * _start(stack, obj, cleanup, ps_strings); 1737 * 1738 * Notes: 1739 * - obj and cleanup are the auxiliary and termination 1740 * vectors. They are fixed up by ld.elf_so. 1741 * - ps_strings is a NetBSD extension. 1742 */ 1743 tf->tf_regs[_R_A0] = (intptr_t)stack; 1744 tf->tf_regs[_R_A1] = 0; 1745 tf->tf_regs[_R_A2] = 0; 1746 tf->tf_regs[_R_A3] = p->p_psstrp; 1747 1748 l->l_md.md_ss_addr = 0; 1749 } 1750 1751 #ifdef __HAVE_BOOTINFO_H 1752 /* 1753 * Machine dependent system variables. 1754 */ 1755 static int 1756 sysctl_machdep_booted_kernel(SYSCTLFN_ARGS) 1757 { 1758 struct btinfo_bootpath *bibp; 1759 struct sysctlnode node; 1760 1761 bibp = lookup_bootinfo(BTINFO_BOOTPATH); 1762 if(!bibp) 1763 return(ENOENT); /* ??? */ 1764 1765 node = *rnode; 1766 node.sysctl_data = bibp->bootpath; 1767 node.sysctl_size = sizeof(bibp->bootpath); 1768 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1769 } 1770 #endif 1771 1772 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 1773 { 1774 1775 sysctl_createv(clog, 0, NULL, NULL, 1776 CTLFLAG_PERMANENT, 1777 CTLTYPE_NODE, "machdep", NULL, 1778 NULL, 0, NULL, 0, 1779 CTL_MACHDEP, CTL_EOL); 1780 1781 sysctl_createv(clog, 0, NULL, NULL, 1782 CTLFLAG_PERMANENT, 1783 CTLTYPE_STRUCT, "console_device", NULL, 1784 sysctl_consdev, 0, NULL, sizeof(dev_t), 1785 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 1786 #ifdef __HAVE_BOOTINFO_H 1787 sysctl_createv(clog, 0, NULL, NULL, 1788 CTLFLAG_PERMANENT, 1789 CTLTYPE_STRING, "booted_kernel", NULL, 1790 sysctl_machdep_booted_kernel, 0, NULL, 0, 1791 CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); 1792 #endif 1793 sysctl_createv(clog, 0, NULL, NULL, 1794 CTLFLAG_PERMANENT, 1795 CTLTYPE_STRING, "root_device", NULL, 1796 sysctl_root_device, 0, NULL, 0, 1797 CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); 1798 sysctl_createv(clog, 0, NULL, NULL, 1799 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 1800 CTLTYPE_INT, "llsc", NULL, 1801 NULL, MIPS_HAS_LLSC, NULL, 0, 1802 CTL_MACHDEP, CPU_LLSC, CTL_EOL); 1803 #ifdef MIPS3_LOONGSON2 1804 sysctl_createv(clog, 0, NULL, NULL, 1805 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 1806 CTLTYPE_INT, "loongson-mmi", NULL, 1807 NULL, MIPS_HAS_LMMI, NULL, 0, 1808 CTL_MACHDEP, CPU_LMMI, CTL_EOL); 1809 #endif 1810 sysctl_createv(clog, 0, NULL, NULL, 1811 CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE, 1812 CTLTYPE_INT, "fpu_present", NULL, 1813 NULL, 1814 #ifdef NOFPU 1815 0, 1816 #else 1817 1, 1818 #endif 1819 NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); 1820 } 1821 1822 /* 1823 * These are imported from platform-specific code. 1824 * XXX Should be declared in a header file. 1825 */ 1826 extern phys_ram_seg_t mem_clusters[]; 1827 extern int mem_cluster_cnt; 1828 1829 /* 1830 * These variables are needed by /sbin/savecore. 1831 */ 1832 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 1833 int dumpsize = 0; /* pages */ 1834 long dumplo = 0; /* blocks */ 1835 1836 struct pcb dumppcb; 1837 1838 /* 1839 * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers. 1840 */ 1841 int 1842 cpu_dumpsize(void) 1843 { 1844 int size; 1845 1846 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) + 1847 ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t)); 1848 if (roundup(size, dbtob(1)) != dbtob(1)) 1849 return (-1); 1850 1851 return (1); 1852 } 1853 1854 /* 1855 * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped. 1856 */ 1857 u_long 1858 cpu_dump_mempagecnt(void) 1859 { 1860 u_long i, n; 1861 1862 n = 0; 1863 for (i = 0; i < mem_cluster_cnt; i++) 1864 n += atop(mem_clusters[i].size); 1865 return (n); 1866 } 1867 1868 /* 1869 * cpu_dump: dump machine-dependent kernel core dump headers. 1870 */ 1871 int 1872 cpu_dump(void) 1873 { 1874 int (*dump)(dev_t, daddr_t, void *, size_t); 1875 char buf[dbtob(1)]; 1876 kcore_seg_t *segp; 1877 cpu_kcore_hdr_t *cpuhdrp; 1878 phys_ram_seg_t *memsegp; 1879 const struct bdevsw *bdev; 1880 int i; 1881 1882 bdev = bdevsw_lookup(dumpdev); 1883 if (bdev == NULL) 1884 return (ENXIO); 1885 1886 dump = bdev->d_dump; 1887 1888 memset(buf, 0, sizeof buf); 1889 segp = (kcore_seg_t *)buf; 1890 cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))]; 1891 memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) + 1892 ALIGN(sizeof(*cpuhdrp))]; 1893 1894 /* 1895 * Generate a segment header. 1896 */ 1897 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 1898 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); 1899 1900 /* 1901 * Add the machine-dependent header info. 1902 */ 1903 if (MIPS_HAS_R4K_MMU) { 1904 cpuhdrp->archlevel = 3; 1905 cpuhdrp->pg_shift = MIPS3_PG_SHIFT; 1906 cpuhdrp->pg_frame = MIPS3_PG_FRAME; 1907 cpuhdrp->pg_v = MIPS3_PG_V; 1908 } else { 1909 cpuhdrp->archlevel = 1; 1910 cpuhdrp->pg_shift = MIPS1_PG_SHIFT; 1911 cpuhdrp->pg_frame = MIPS1_PG_FRAME; 1912 cpuhdrp->pg_v = MIPS1_PG_V; 1913 } 1914 cpuhdrp->sysmappa = MIPS_KSEG0_TO_PHYS(curcpu()->ci_pmap_kern_segtab); 1915 cpuhdrp->nmemsegs = mem_cluster_cnt; 1916 1917 /* 1918 * Fill in the memory segment descriptors. 1919 */ 1920 for (i = 0; i < mem_cluster_cnt; i++) { 1921 memsegp[i].start = mem_clusters[i].start; 1922 memsegp[i].size = mem_clusters[i].size; 1923 } 1924 1925 return (dump(dumpdev, dumplo, (void *)buf, dbtob(1))); 1926 } 1927 1928 /* 1929 * This is called by main to set dumplo and dumpsize. 1930 * Dumps always skip the first CLBYTES of disk space 1931 * in case there might be a disk label stored there. 1932 * If there is extra space, put dump at the end to 1933 * reduce the chance that swapping trashes it. 1934 */ 1935 void 1936 cpu_dumpconf(void) 1937 { 1938 int nblks, dumpblks; /* size of dump area */ 1939 1940 if (dumpdev == NODEV) 1941 goto bad; 1942 nblks = bdev_size(dumpdev); 1943 if (nblks <= ctod(1)) 1944 goto bad; 1945 1946 dumpblks = cpu_dumpsize(); 1947 if (dumpblks < 0) 1948 goto bad; 1949 dumpblks += ctod(cpu_dump_mempagecnt()); 1950 1951 /* If dump won't fit (incl. room for possible label), punt. */ 1952 if (dumpblks > (nblks - ctod(1))) 1953 goto bad; 1954 1955 /* Put dump at end of partition */ 1956 dumplo = nblks - dumpblks; 1957 1958 /* dumpsize is in page units, and doesn't include headers. */ 1959 dumpsize = cpu_dump_mempagecnt(); 1960 return; 1961 1962 bad: 1963 dumpsize = 0; 1964 } 1965 1966 /* 1967 * Dump the kernel's image to the swap partition. 1968 */ 1969 #define BYTES_PER_DUMP PAGE_SIZE 1970 1971 void 1972 dumpsys(void) 1973 { 1974 u_long totalbytesleft, bytes, i, n, memcl; 1975 u_long maddr; 1976 int psize; 1977 daddr_t blkno; 1978 const struct bdevsw *bdev; 1979 int (*dump)(dev_t, daddr_t, void *, size_t); 1980 int error; 1981 1982 /* Save registers. */ 1983 savectx(&dumppcb); 1984 1985 if (dumpdev == NODEV) 1986 return; 1987 bdev = bdevsw_lookup(dumpdev); 1988 if (bdev == NULL || bdev->d_psize == NULL) 1989 return; 1990 1991 /* 1992 * For dumps during autoconfiguration, 1993 * if dump device has already configured... 1994 */ 1995 if (dumpsize == 0) 1996 cpu_dumpconf(); 1997 if (dumplo <= 0) { 1998 printf("\ndump to dev %u,%u not possible\n", major(dumpdev), 1999 minor(dumpdev)); 2000 return; 2001 } 2002 printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), 2003 minor(dumpdev), dumplo); 2004 2005 psize = bdev_size(dumpdev); 2006 printf("dump "); 2007 if (psize == -1) { 2008 printf("area unavailable\n"); 2009 return; 2010 } 2011 2012 /* XXX should purge all outstanding keystrokes. */ 2013 2014 if ((error = cpu_dump()) != 0) 2015 goto err; 2016 2017 totalbytesleft = ptoa(cpu_dump_mempagecnt()); 2018 blkno = dumplo + cpu_dumpsize(); 2019 dump = bdev->d_dump; 2020 error = 0; 2021 2022 for (memcl = 0; memcl < mem_cluster_cnt; memcl++) { 2023 maddr = mem_clusters[memcl].start; 2024 bytes = mem_clusters[memcl].size; 2025 2026 for (i = 0; i < bytes; i += n, totalbytesleft -= n) { 2027 void *maddr_va; 2028 2029 /* Print out how many MBs we have left to go. */ 2030 if ((totalbytesleft % (1024*1024)) == 0) 2031 printf_nolog("%ld ", 2032 totalbytesleft / (1024 * 1024)); 2033 2034 /* Limit size for next transfer. */ 2035 n = bytes - i; 2036 if (n > BYTES_PER_DUMP) 2037 n = BYTES_PER_DUMP; 2038 2039 #ifdef _LP64 2040 maddr_va = (void *)MIPS_PHYS_TO_XKPHYS_CACHED(maddr); 2041 #else 2042 maddr_va = (void *)MIPS_PHYS_TO_KSEG0(maddr); 2043 #endif 2044 error = (*dump)(dumpdev, blkno, maddr_va, n); 2045 if (error) 2046 goto err; 2047 maddr += n; 2048 blkno += btodb(n); /* XXX? */ 2049 2050 /* XXX should look for keystrokes, to cancel. */ 2051 } 2052 } 2053 2054 err: 2055 switch (error) { 2056 2057 case ENXIO: 2058 printf("device bad\n"); 2059 break; 2060 2061 case EFAULT: 2062 printf("device not ready\n"); 2063 break; 2064 2065 case EINVAL: 2066 printf("area improper\n"); 2067 break; 2068 2069 case EIO: 2070 printf("i/o error\n"); 2071 break; 2072 2073 case EINTR: 2074 printf("aborted from console\n"); 2075 break; 2076 2077 case 0: 2078 printf("succeeded\n"); 2079 break; 2080 2081 default: 2082 printf("error %d\n", error); 2083 break; 2084 } 2085 printf("\n\n"); 2086 delay(5000000); /* 5 seconds */ 2087 } 2088 2089 void 2090 mips_init_msgbuf(void) 2091 { 2092 vsize_t sz = (vsize_t)round_page(MSGBUFSIZE); 2093 vsize_t reqsz = sz; 2094 uvm_physseg_t bank = uvm_physseg_get_last(); 2095 #ifndef _LP64 2096 /* 2097 * First the physical segment that can be mapped to KSEG0 2098 */ 2099 for (; uvm_physseg_valid_p(bank); bank = uvm_physseg_get_prev(bank)) { 2100 if (uvm_physseg_get_avail_start(bank) + atop(sz) <= atop(MIPS_PHYS_MASK)) 2101 break; 2102 } 2103 #endif 2104 2105 paddr_t start = uvm_physseg_get_start(bank); 2106 paddr_t end = uvm_physseg_get_end(bank); 2107 2108 /* shrink so that it'll fit in the last segment */ 2109 if ((end - start) < atop(sz)) 2110 sz = ptoa(end - start); 2111 2112 end -= atop(sz); 2113 uvm_physseg_unplug(end, atop(sz)); 2114 2115 #ifdef _LP64 2116 msgbufaddr = (void *) MIPS_PHYS_TO_XKPHYS_CACHED(ptoa(end)); 2117 #else 2118 msgbufaddr = (void *) MIPS_PHYS_TO_KSEG0(ptoa(end)); 2119 #endif 2120 initmsgbuf(msgbufaddr, sz); 2121 2122 /* warn if the message buffer had to be shrunk */ 2123 if (sz != reqsz) 2124 printf("WARNING: %"PRIdVSIZE" bytes not available for msgbuf " 2125 "in last cluster (%"PRIdVSIZE" used)\n", reqsz, sz); 2126 } 2127 2128 void 2129 mips_init_lwp0_uarea(void) 2130 { 2131 struct lwp * const l = &lwp0; 2132 vaddr_t v; 2133 2134 if (l->l_addr == NULL) { 2135 v = uvm_pageboot_alloc(USPACE); 2136 uvm_lwp_setuarea(&lwp0, v); 2137 } else { 2138 v = (vaddr_t)l->l_addr; 2139 } 2140 2141 l->l_md.md_utf = (struct trapframe *)(v + USPACE) - 1; 2142 struct pcb * const pcb = lwp_getpcb(l); 2143 /* 2144 * Now zero out the only two areas of the uarea that we care about. 2145 */ 2146 memset(l->l_md.md_utf, 0, sizeof(*l->l_md.md_utf)); 2147 memset(pcb, 0, sizeof(*pcb)); 2148 2149 pcb->pcb_context.val[_L_SR] = MIPS_SR_INT_IE 2150 | (ipl_sr_map.sr_bits[IPL_SCHED] ^ MIPS_INT_MASK); 2151 #ifdef __mips_n32 2152 pcb->pcb_context.val[_L_SR] |= MIPS_SR_KX; 2153 l->l_md.md_utf->tf_regs[_R_SR] = MIPS_SR_KX; 2154 #endif 2155 #ifdef _LP64 2156 pcb->pcb_context.val[_L_SR] |= MIPS_SR_KX | MIPS_SR_UX; 2157 l->l_md.md_utf->tf_regs[_R_SR] = MIPS_SR_KX | MIPS_SR_UX; 2158 #endif 2159 } 2160 2161 int mips_poolpage_vmfreelist = VM_FREELIST_DEFAULT; 2162 2163 #define HALFGIG ((paddr_t)512 * 1024 * 1024) 2164 #define FOURGIG ((paddr_t)4 * 1024 * 1024 * 1024) 2165 2166 void 2167 mips_page_physload(vaddr_t vkernstart, vaddr_t vkernend, 2168 const phys_ram_seg_t *segs, size_t nseg, 2169 const struct mips_vmfreelist *flp, size_t nfl) 2170 { 2171 const paddr_t kernstart = MIPS_KSEG0_TO_PHYS(trunc_page(vkernstart)); 2172 const paddr_t kernend = MIPS_KSEG0_TO_PHYS(round_page(vkernend)); 2173 #if defined(VM_FREELIST_FIRST4G) || defined(VM_FREELIST_FIRST512M) 2174 #ifdef VM_FREELIST_FIRST512M 2175 bool need512m = false; 2176 #endif 2177 #ifdef VM_FREELIST_FIRST4G 2178 bool need4g = false; 2179 #endif 2180 2181 /* 2182 * Do a first pass and see what ranges memory we have to deal with. 2183 */ 2184 for (size_t i = 0; i < nseg; i++) { 2185 #ifdef VM_FREELIST_FIRST4G 2186 if (round_page(segs[i].start + segs[i].size) > FOURGIG) { 2187 need4g = true; 2188 } 2189 #endif 2190 #ifdef VM_FREELIST_FIRST512M 2191 if (round_page(segs[i].start + segs[i].size) > HALFGIG) { 2192 need512m = true; 2193 #if !defined(_LP64) 2194 mips_poolpage_vmfreelist = VM_FREELIST_FIRST512M; 2195 #endif 2196 } 2197 #endif 2198 } 2199 #endif /* VM_FREELIST_FIRST512M || VM_FREELIST_FIRST4G */ 2200 2201 for (; nseg-- > 0; segs++) { 2202 /* 2203 * Make sure everything is in page units. 2204 */ 2205 paddr_t segstart = round_page(segs->start); 2206 const paddr_t segfinish = trunc_page(segs->start + segs->size); 2207 2208 if (segstart >= segfinish) { 2209 /* 2210 * This is purely cosmetic, to avoid output like 2211 * phys segment: 0xffffffffffffe000 @ 0xffb6000 2212 * when a segment starts and finishes in the same page. 2213 */ 2214 printf("phys segment: %#"PRIxPADDR" @ %#"PRIxPADDR 2215 " (short)\n", (paddr_t)segs->size, segstart); 2216 continue; 2217 } 2218 2219 printf("phys segment: %#"PRIxPADDR" @ %#"PRIxPADDR"\n", 2220 segfinish - segstart, segstart); 2221 2222 /* 2223 * Page 0 is reserved for exception vectors. 2224 */ 2225 if (segstart == 0) { 2226 segstart = PAGE_SIZE; 2227 } 2228 while (segstart < segfinish) { 2229 int freelist = -1; /* unknown freelist */ 2230 paddr_t segend = segfinish; 2231 for (size_t i = 0; i < nfl; i++) { 2232 /* 2233 * If this segment doesn't overlap the freelist 2234 * at all, skip it. 2235 */ 2236 if (segstart >= flp[i].fl_end 2237 || segend <= flp[i].fl_start) 2238 continue; 2239 /* 2240 * If the start of this segment starts before 2241 * the start of the freelist, then limit the 2242 * segment to loaded to the part that doesn't 2243 * match this freelist and fall back to normal 2244 * freelist matching. 2245 */ 2246 if (segstart < flp[i].fl_start) { 2247 segstart = flp[i].fl_start; 2248 break; 2249 } 2250 2251 /* 2252 * We've matched this freelist so remember it. 2253 */ 2254 freelist = flp->fl_freelist; 2255 2256 /* 2257 * If this segment extends past the end of this 2258 * freelist, bound to segment to the freelist. 2259 */ 2260 if (segend > flp[i].fl_end) 2261 segend = flp[i].fl_end; 2262 break; 2263 } 2264 /* 2265 * If we didn't match one of the port dependent 2266 * freelists, let's try the common ones. 2267 */ 2268 if (freelist == -1) { 2269 #ifdef VM_FREELIST_FIRST512M 2270 if (need512m && segstart < HALFGIG) { 2271 freelist = VM_FREELIST_FIRST512M; 2272 if (segend > HALFGIG) 2273 segend = HALFGIG; 2274 } else 2275 #endif 2276 #ifdef VM_FREELIST_FIRST4G 2277 if (need4g && segstart < FOURGIG) { 2278 freelist = VM_FREELIST_FIRST4G; 2279 if (segend > FOURGIG) 2280 segend = FOURGIG; 2281 } else 2282 #endif 2283 freelist = VM_FREELIST_DEFAULT; 2284 } 2285 2286 /* 2287 * Make sure the memory we provide to uvm doesn't 2288 * include the kernel. 2289 */ 2290 if (segstart < kernend && segend > kernstart) { 2291 if (segstart < kernstart) { 2292 /* 2293 * Only add the memory before the 2294 * kernel. 2295 */ 2296 segend = kernstart; 2297 } else if (segend > kernend) { 2298 /* 2299 * Only add the memory after the 2300 * kernel. 2301 */ 2302 segstart = kernend; 2303 } else { 2304 /* 2305 * Just skip the segment entirely since 2306 * it's completely inside the kernel. 2307 */ 2308 printf("skipping %#"PRIxPADDR" @ %#"PRIxPADDR" (kernel)\n", 2309 segend - segstart, segstart); 2310 break; 2311 } 2312 } 2313 2314 /* 2315 * Now we give this segment to uvm. 2316 */ 2317 printf("adding %#"PRIxPADDR" @ %#"PRIxPADDR" to freelist %d\n", 2318 segend - segstart, segstart, freelist); 2319 paddr_t first = atop(segstart); 2320 paddr_t last = atop(segend); 2321 uvm_page_physload(first, last, first, last, freelist); 2322 2323 /* 2324 * Start where we finished. 2325 */ 2326 segstart = segend; 2327 } 2328 } 2329 } 2330 2331 /* 2332 * Start a new LWP 2333 */ 2334 void 2335 startlwp(void *arg) 2336 { 2337 ucontext_t * const uc = arg; 2338 lwp_t * const l = curlwp; 2339 int error __diagused; 2340 2341 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); 2342 KASSERT(error == 0); 2343 2344 kmem_free(uc, sizeof(ucontext_t)); 2345 userret(l); 2346 } 2347 2348 #ifdef COMPAT_NETBSD32 2349 /* 2350 * Start a new LWP 2351 */ 2352 void 2353 startlwp32(void *arg) 2354 { 2355 ucontext32_t * const uc = arg; 2356 lwp_t * const l = curlwp; 2357 int error __diagused; 2358 2359 error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags); 2360 KASSERT(error == 0); 2361 2362 /* Note: we are freeing ucontext_t, not ucontext32_t. */ 2363 kmem_free(uc, sizeof(ucontext_t)); 2364 userret(l); 2365 } 2366 #endif /* COMPAT_NETBSD32 */ 2367 2368 #ifdef PARANOIA 2369 void 2370 std_splsw_test(void) 2371 { 2372 struct cpu_info * const ci = curcpu(); 2373 const uint32_t * const sr_map = ipl_sr_map.sr_bits; 2374 uint32_t status = mips_cp0_status_read(); 2375 uint32_t sr_bits; 2376 int s; 2377 2378 KASSERT((status & MIPS_SR_INT_IE) == 0); 2379 2380 sr_bits = sr_map[IPL_NONE]; 2381 2382 splx(IPL_NONE); 2383 status = mips_cp0_status_read() & MIPS_INT_MASK; 2384 KASSERT(status == MIPS_INT_MASK); 2385 KASSERT(ci->ci_cpl == IPL_NONE); 2386 2387 s = splsoftclock(); 2388 status = mips_cp0_status_read() & MIPS_INT_MASK; 2389 KASSERT((status ^ sr_map[IPL_SOFTCLOCK]) == MIPS_INT_MASK); 2390 KASSERT(ci->ci_cpl == IPL_SOFTCLOCK); 2391 KASSERT(s == IPL_NONE); 2392 2393 s = splsoftbio(); 2394 status = mips_cp0_status_read() & MIPS_INT_MASK; 2395 KASSERT((status ^ sr_map[IPL_SOFTBIO]) == MIPS_INT_MASK); 2396 KASSERT(ci->ci_cpl == IPL_SOFTBIO); 2397 KASSERT(s == IPL_SOFTCLOCK); 2398 2399 s = splsoftnet(); 2400 status = mips_cp0_status_read() & MIPS_INT_MASK; 2401 KASSERT((status ^ sr_map[IPL_SOFTNET]) == MIPS_INT_MASK); 2402 KASSERT(ci->ci_cpl == IPL_SOFTNET); 2403 KASSERT(s == IPL_SOFTBIO); 2404 2405 s = splsoftserial(); 2406 status = mips_cp0_status_read() & MIPS_INT_MASK; 2407 KASSERT((status ^ sr_map[IPL_SOFTSERIAL]) == MIPS_INT_MASK); 2408 KASSERT(ci->ci_cpl == IPL_SOFTSERIAL); 2409 KASSERT(s == IPL_SOFTNET); 2410 2411 s = splvm(); 2412 status = mips_cp0_status_read() & MIPS_INT_MASK; 2413 KASSERT((status ^ sr_map[IPL_VM]) == MIPS_INT_MASK); 2414 KASSERT(ci->ci_cpl == IPL_VM); 2415 KASSERT(s == IPL_SOFTSERIAL); 2416 2417 s = splsched(); 2418 status = mips_cp0_status_read() & MIPS_INT_MASK; 2419 KASSERT((status ^ sr_map[IPL_SCHED]) == MIPS_INT_MASK); 2420 KASSERT(ci->ci_cpl == IPL_SCHED); 2421 KASSERT(s == IPL_VM); 2422 2423 s = splhigh(); 2424 status = mips_cp0_status_read() & MIPS_INT_MASK; 2425 KASSERT((status ^ sr_map[IPL_HIGH]) == MIPS_INT_MASK); 2426 KASSERT(ci->ci_cpl == IPL_HIGH); 2427 KASSERT(s == IPL_SCHED); 2428 2429 splx(IPL_NONE); 2430 status = mips_cp0_status_read() & MIPS_INT_MASK; 2431 KASSERT(status == MIPS_INT_MASK); 2432 KASSERT(ci->ci_cpl == IPL_NONE); 2433 2434 for (int r = IPL_SOFTCLOCK; r <= IPL_HIGH; r++) { 2435 /* 2436 * As IPL increases, more intrs may be masked but no intrs 2437 * may become unmasked. 2438 */ 2439 KASSERT((sr_map[r] & sr_bits) == sr_bits); 2440 sr_bits |= sr_map[r]; 2441 s = splraise(r); 2442 KASSERT(s == IPL_NONE); 2443 2444 for (int t = r; t <= IPL_HIGH; t++) { 2445 int o = splraise(t); 2446 status = mips_cp0_status_read() & MIPS_INT_MASK; 2447 KASSERT((status ^ sr_map[t]) == MIPS_INT_MASK); 2448 KASSERT(ci->ci_cpl == t); 2449 KASSERT(o == r); 2450 2451 splx(o); 2452 status = mips_cp0_status_read() & MIPS_INT_MASK; 2453 KASSERT((status ^ sr_map[r]) == MIPS_INT_MASK); 2454 KASSERT(ci->ci_cpl == r); 2455 } 2456 2457 splx(s); 2458 status = mips_cp0_status_read() & MIPS_INT_MASK; 2459 KASSERT((status ^ sr_map[s]) == MIPS_INT_MASK); 2460 KASSERT(ci->ci_cpl == s); 2461 } 2462 2463 status = mips_cp0_status_read() & MIPS_INT_MASK; 2464 KASSERT(status == MIPS_INT_MASK); 2465 KASSERT(ci->ci_cpl == IPL_NONE); 2466 } 2467 2468 #endif /* PARANOIA */ 2469 2470 bool 2471 mm_md_direct_mapped_phys(paddr_t pa, vaddr_t *vap) 2472 { 2473 #ifdef _LP64 2474 if (MIPS_XKSEG_P(pa)) { 2475 *vap = MIPS_PHYS_TO_XKPHYS_CACHED(pa); 2476 return true; 2477 } 2478 #endif 2479 if (MIPS_KSEG0_P(pa)) { 2480 *vap = MIPS_PHYS_TO_KSEG0(pa); 2481 return true; 2482 } 2483 return false; 2484 } 2485 2486 bool 2487 mm_md_page_color(paddr_t pa, int *colorp) 2488 { 2489 if (MIPS_CACHE_VIRTUAL_ALIAS) { 2490 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 2491 KASSERT(pg != NULL); 2492 struct vm_page_md * const mdpg = VM_PAGE_TO_MD(pg); 2493 *colorp = atop(mdpg->mdpg_first.pv_va); 2494 return !mips_cache_badalias(pa, mdpg->mdpg_first.pv_va); 2495 } 2496 *colorp = 0; 2497 return true; 2498 } 2499 2500 int 2501 mm_md_physacc(paddr_t pa, vm_prot_t prot) 2502 { 2503 2504 return (pa < ctob(physmem)) ? 0 : EFAULT; 2505 } 2506 2507 int 2508 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) 2509 { 2510 const vaddr_t v = (vaddr_t)ptr; 2511 2512 #ifdef _LP64 2513 extern char end[]; 2514 2515 /* For any address < XKPHYS cached address 0, fault */ 2516 if (v < MIPS_PHYS_TO_XKPHYS_CACHED(0)) { 2517 return EFAULT; 2518 } 2519 2520 /* If address < XKPHY(end of message buffer), good! */ 2521 if (v < MIPS_PHYS_TO_XKPHYS_CACHED(pmap_limits.avail_end + 2522 mips_round_page(MSGBUFSIZE))) { 2523 /* XXX holes in RAM (eg, EdgeRouter 4) */ 2524 *handled = true; 2525 return 0; 2526 } 2527 2528 /* If address in KSEG0 and is before end of kernel, good! */ 2529 if (MIPS_KSEG0_P(v) && v < (vaddr_t)end) { 2530 *handled = true; 2531 return 0; 2532 } 2533 2534 /* Otherwise, fall back to the uvm_kernacc() check. */ 2535 #else 2536 if (v < MIPS_KSEG0_START) { 2537 return EFAULT; 2538 } 2539 if (v < MIPS_PHYS_TO_KSEG0(pmap_limits.avail_end + 2540 mips_round_page(MSGBUFSIZE))) { 2541 *handled = true; 2542 return 0; 2543 } 2544 if (v < MIPS_KSEG2_START) { 2545 return EFAULT; 2546 } 2547 #endif 2548 *handled = false; 2549 return 0; 2550 } 2551 2552 #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 2553 static void 2554 mips_watchpoint_init(void) 2555 { 2556 /* 2557 * determine number of CPU watchpoints 2558 */ 2559 curcpu()->ci_cpuwatch_count = cpuwatch_discover(); 2560 } 2561 #endif 2562 2563 2564 /* 2565 * Process the tail end of a posix_spawn() for the child. 2566 */ 2567 void 2568 cpu_spawn_return(struct lwp *l) 2569 { 2570 userret(l); 2571 } 2572