1 /* $NetBSD: mips_machdep.c,v 1.129 2002/05/03 03:50:11 rafal 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. Neither the "Broadcom Corporation" name nor any 54 * trademark or logo of Broadcom Corporation may be used to endorse or 55 * promote products derived from this software without the prior written 56 * permission of Broadcom Corporation. 57 * 58 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 59 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 60 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 61 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 62 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 63 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 64 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 66 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 67 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 68 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 */ 70 71 /*- 72 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 73 * All rights reserved. 74 * 75 * This code is derived from software contributed to The NetBSD Foundation 76 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 77 * NASA Ames Research Center and by Chris Demetriou. 78 * 79 * Redistribution and use in source and binary forms, with or without 80 * modification, are permitted provided that the following conditions 81 * are met: 82 * 1. Redistributions of source code must retain the above copyright 83 * notice, this list of conditions and the following disclaimer. 84 * 2. Redistributions in binary form must reproduce the above copyright 85 * notice, this list of conditions and the following disclaimer in the 86 * documentation and/or other materials provided with the distribution. 87 * 3. All advertising materials mentioning features or use of this software 88 * must display the following acknowledgement: 89 * This product includes software developed by the NetBSD 90 * Foundation, Inc. and its contributors. 91 * 4. Neither the name of The NetBSD Foundation nor the names of its 92 * contributors may be used to endorse or promote products derived 93 * from this software without specific prior written permission. 94 * 95 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 96 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 97 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 98 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 99 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 100 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 101 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 102 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 103 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 104 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 105 * POSSIBILITY OF SUCH DAMAGE. 106 */ 107 108 /* 109 * Copyright 1996 The Board of Trustees of The Leland Stanford 110 * Junior University. All Rights Reserved. 111 * 112 * Permission to use, copy, modify, and distribute this 113 * software and its documentation for any purpose and without 114 * fee is hereby granted, provided that the above copyright 115 * notice appear in all copies. Stanford University 116 * makes no representations about the suitability of this 117 * software for any purpose. It is provided "as is" without 118 * express or implied warranty. 119 */ 120 121 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 122 123 __KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.129 2002/05/03 03:50:11 rafal Exp $"); 124 125 #include "opt_cputype.h" 126 #include "opt_compat_netbsd.h" 127 #include "opt_compat_ultrix.h" 128 129 #include <sys/param.h> 130 #include <sys/systm.h> 131 #include <sys/exec.h> 132 #include <sys/reboot.h> 133 #include <sys/mount.h> /* fsid_t for syscallargs */ 134 #include <sys/proc.h> 135 #include <sys/buf.h> 136 #include <sys/clist.h> 137 #include <sys/signal.h> 138 #include <sys/signalvar.h> 139 #include <sys/syscallargs.h> 140 #include <sys/user.h> 141 #include <sys/msgbuf.h> 142 #include <sys/conf.h> 143 #include <sys/core.h> 144 #include <sys/kcore.h> 145 #include <machine/kcore.h> 146 147 #include <uvm/uvm_extern.h> 148 149 #include <mips/cache.h> 150 #include <mips/regnum.h> 151 #include <mips/locore.h> 152 #include <mips/psl.h> 153 #include <mips/pte.h> 154 #include <machine/cpu.h> 155 156 #if defined(MIPS32) || defined(MIPS64) 157 #include <mips/mipsNN.h> /* MIPS32/MIPS64 registers */ 158 #endif 159 160 /* Internal routines. */ 161 int cpu_dumpsize(void); 162 u_long cpu_dump_mempagecnt(void); 163 int cpu_dump(void); 164 165 #if defined(MIPS1) 166 static void mips1_vector_init(void); 167 extern long *mips1_locoresw[]; 168 #endif 169 170 #if defined(MIPS3) 171 #if defined(MIPS3_5900) 172 static void r5900_vector_init(void); 173 extern long *mips5900_locoresw[]; 174 #else 175 static void mips3_vector_init(void); 176 extern long *mips3_locoresw[]; 177 #endif 178 #endif 179 180 #if defined(MIPS32) 181 static void mips32_vector_init(void); 182 extern long *mips32_locoresw[]; 183 #endif 184 185 #if defined(MIPS64) 186 static void mips64_vector_init(void); 187 extern long *mips64_locoresw[]; 188 #endif 189 190 mips_locore_jumpvec_t mips_locore_jumpvec; 191 192 long *mips_locoresw[3]; 193 194 int cpu_arch; 195 int cpu_mhz; 196 int mips_num_tlb_entries; 197 int mips_cpu_flags; 198 int mips_has_llsc; 199 int mips_has_r4k_mmu; 200 int mips3_pg_cached; 201 202 struct user *proc0paddr; 203 struct proc *fpcurproc; 204 struct pcb *curpcb; 205 struct segtab *segbase; 206 207 caddr_t msgbufaddr; 208 209 #ifdef MIPS3_4100 /* VR4100 core */ 210 int default_pg_mask = 0x00001800; 211 #endif 212 213 struct pridtab { 214 int cpu_cid; 215 int cpu_pid; 216 int cpu_rev; /* -1 == wildcard */ 217 int cpu_isa; /* -1 == probed (mips32/mips64) */ 218 int cpu_ntlb; /* -1 == unknown, 0 == probed */ 219 int cpu_flags; 220 char *cpu_name; 221 }; 222 223 /* 224 * Assumptions: 225 * - All MIPS3+ have an r4k-style MMU. _Many_ assumptions throughout 226 * much of the mips code about this. Includes overloaded usage of 227 * MIPS3_PLUS. 228 * - All MIPS3+ use the same exception model (cp0 status, cause bits, 229 * etc). _Many_ assumptions throughout much of the mips code about 230 * this. Includes overloaded usage of MIPS3_PLUS. 231 * - All MIPS3+ have a count register. MIPS_HAS_CLOCK in <mips/cpu.h> 232 * will need to be revised if this is false. 233 */ 234 #define MIPS32_FLAGS CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV 235 #define MIPS64_FLAGS MIPS32_FLAGS /* same as MIPS32 flags (for now) */ 236 237 static const struct pridtab *mycpu; 238 239 static const struct pridtab cputab[] = { 240 { 0, MIPS_R2000, -1, CPU_ARCH_MIPS1, 64, 241 0, "MIPS R2000 CPU" }, 242 { 0, MIPS_R3000, MIPS_REV_R3000, CPU_ARCH_MIPS1, 64, 243 0, "MIPS R3000 CPU" }, 244 { 0, MIPS_R3000, MIPS_REV_R3000A, CPU_ARCH_MIPS1, 64, 245 0, "MIPS R3000A CPU" }, 246 { 0, MIPS_R6000, -1, CPU_ARCH_MIPS2, 32, 247 MIPS_NOT_SUPP, "MIPS R6000 CPU" }, 248 249 /* 250 * rev 0x00 and 0x30 are R4000, 0x40, 0x50 and 0x60 are R4400. 251 * should we allow ranges and use 0x00 - 0x3f for R4000 and 252 * 0x40 - 0xff for R4400? 253 */ 254 { 0, MIPS_R4000, MIPS_REV_R4000_A, CPU_ARCH_MIPS3, 48, 255 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 256 "MIPS R4000 CPU" }, 257 { 0, MIPS_R4000, MIPS_REV_R4000_B, CPU_ARCH_MIPS3, 48, 258 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 259 "MIPS R4000 CPU" }, 260 { 0, MIPS_R4000, MIPS_REV_R4400_A, CPU_ARCH_MIPS3, 48, 261 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 262 "MIPS R4400 CPU" }, 263 { 0, MIPS_R4000, MIPS_REV_R4400_B, CPU_ARCH_MIPS3, 48, 264 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 265 "MIPS R4400 CPU" }, 266 { 0, MIPS_R4000, MIPS_REV_R4400_C, CPU_ARCH_MIPS3, 48, 267 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 268 "MIPS R4400 CPU" }, 269 270 { 0, MIPS_R3LSI, -1, CPU_ARCH_MIPS1, -1, 271 MIPS_NOT_SUPP, "LSI Logic R3000 derivative" }, 272 { 0, MIPS_R6000A, -1, CPU_ARCH_MIPS2, 32, 273 MIPS_NOT_SUPP, "MIPS R6000A CPU" }, 274 { 0, MIPS_R3IDT, -1, CPU_ARCH_MIPS1, -1, 275 MIPS_NOT_SUPP, "IDT R3041 or RC36100 CPU" }, 276 { 0, MIPS_R4100, -1, CPU_ARCH_MIPS3, 32, 277 CPU_MIPS_R4K_MMU | CPU_MIPS_NO_LLSC, "NEC VR4100 CPU" }, 278 { 0, MIPS_R4200, -1, CPU_ARCH_MIPS3, -1, 279 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "NEC VR4200 CPU" }, 280 { 0, MIPS_R4300, -1, CPU_ARCH_MIPS3, 32, 281 CPU_MIPS_R4K_MMU, "NEC VR4300 CPU" }, 282 { 0, MIPS_R4600, -1, CPU_ARCH_MIPS3, 48, 283 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 284 "QED R4600 Orion CPU" }, 285 { 0, MIPS_R4700, -1, CPU_ARCH_MIPS3, 48, 286 CPU_MIPS_R4K_MMU, "QED R4700 Orion CPU" }, 287 288 { 0, MIPS_R8000, -1, CPU_ARCH_MIPS4, 384, 289 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "MIPS R8000 Blackbird/TFP CPU" }, 290 { 0, MIPS_R10000, -1, CPU_ARCH_MIPS4, 64, 291 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "MIPS R10000 CPU" }, 292 { 0, MIPS_R12000, -1, CPU_ARCH_MIPS4, 64, 293 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "MIPS R12000 CPU" }, 294 { 0, MIPS_R14000, -1, CPU_ARCH_MIPS4, 64, 295 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "MIPS R14000 CPU" }, 296 297 /* XXX 298 * If the Processor Revision ID of the 4650 isn't 0, the following 299 * entry needs to be adjusted. Can't use a wildcard match because 300 * the TX39 series processors share the same Processor ID value. 301 * Or maybe put TX39 CPUs first if the revid doesn't overlap with 302 * the 4650... 303 */ 304 { 0, MIPS_R4650, 0, CPU_ARCH_MIPS3, -1, 305 MIPS_NOT_SUPP /* no MMU! */, "QED R4650 CPU" }, 306 { 0, MIPS_TX3900, MIPS_REV_TX3912, CPU_ARCH_MIPS1, 32, 307 0, "Toshiba TX3912 CPU" }, 308 { 0, MIPS_TX3900, MIPS_REV_TX3922, CPU_ARCH_MIPS1, 64, 309 0, "Toshiba TX3922 CPU" }, 310 { 0, MIPS_TX3900, MIPS_REV_TX3927, CPU_ARCH_MIPS1, 64, 311 0, "Toshiba TX3927 CPU" }, 312 { 0, MIPS_R5000, -1, CPU_ARCH_MIPS4, 48, 313 CPU_MIPS_R4K_MMU | CPU_MIPS_DOUBLE_COUNT, 314 "MIPS R5000 CPU" }, 315 { 0, MIPS_RM5200, -1, CPU_ARCH_MIPS4, 48, 316 CPU_MIPS_R4K_MMU | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT, 317 "QED RM5200 CPU" }, 318 319 /* XXX 320 * The rm7000 rev 2.0 can have 64 tlbs, and has 6 extra interrupts. See 321 * "Migrating to the RM7000 from other MIPS Microprocessors" 322 * for more details. 323 */ 324 { 0, MIPS_RM7000, -1, CPU_ARCH_MIPS4, 48, 325 MIPS_NOT_SUPP | CPU_MIPS_CAUSE_IV | CPU_MIPS_DOUBLE_COUNT, 326 "QED RM7000 CPU" }, 327 328 /* 329 * IDT RC32300 core is a 32 bit MIPS2 processor with 330 * MIPS3/MIPS4 extensions. It has an R4000-style TLB, 331 * while all registers are 32 bits and any 64 bit 332 * instructions like ld/sd/dmfc0/dmtc0 are not allowed. 333 * 334 * note that the Config register has a non-standard base 335 * for IC and DC (2^9 instead of 2^12). 336 * 337 */ 338 { 0, MIPS_RC32300, -1, CPU_ARCH_MIPS3, 16, 339 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "IDT RC32300 CPU" }, 340 { 0, MIPS_RC32364, -1, CPU_ARCH_MIPS3, 16, 341 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "IDT RC32364 CPU" }, 342 { 0, MIPS_RC64470, -1, CPU_ARCH_MIPSx, -1, 343 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "IDT RC64474/RC64475 CPU" }, 344 345 { 0, MIPS_R5400, -1, CPU_ARCH_MIPSx, -1, 346 MIPS_NOT_SUPP | CPU_MIPS_R4K_MMU, "NEC VR5400 CPU" }, 347 { 0, MIPS_R5900, -1, CPU_ARCH_MIPS3, 48, 348 CPU_MIPS_R4K_MMU, "Toshiba R5900 CPU" }, 349 350 #if 0 /* ID collisions : can we use a CU1 test or similar? */ 351 { 0, MIPS_R3SONY, -1, CPU_ARCH_MIPS1, -1, 352 MIPS_NOT_SUPP, "SONY R3000 derivative" }, /* 0x21; crash R4700? */ 353 { 0, MIPS_R3NKK, -1, CPU_ARCH_MIPS1, -1, 354 MIPS_NOT_SUPP, "NKK R3000 derivative" }, /* 0x23; crash R5000? */ 355 #endif 356 357 { MIPS_PRID_CID_MTI, MIPS_4Kc, -1, -1, 0, 358 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, "4Kc" }, 359 { MIPS_PRID_CID_MTI, MIPS_4KEc, -1, -1, 0, 360 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, "4KEc" }, 361 { MIPS_PRID_CID_MTI, MIPS_4KSc, -1, -1, 0, 362 MIPS32_FLAGS | CPU_MIPS_DOUBLE_COUNT, "4KSc" }, 363 { MIPS_PRID_CID_MTI, MIPS_5Kc, -1, -1, 0, 364 MIPS64_FLAGS | CPU_MIPS_DOUBLE_COUNT, "5Kc" }, 365 366 { MIPS_PRID_CID_ALCHEMY, MIPS_AU1000_R1, -1, -1, 0, 367 MIPS32_FLAGS, "Au1000 (Rev 1)" }, 368 { MIPS_PRID_CID_ALCHEMY, MIPS_AU1000_R2, -1, -1, 0, 369 MIPS32_FLAGS, "Au1000 (Rev 2)" }, 370 371 /* The SB1 CPUs use a CCA of 5 - "Cacheable Coherent Shareable" */ 372 { MIPS_PRID_CID_SIBYTE, MIPS_SB1, -1, -1, 0, 373 MIPS64_FLAGS | CPU_MIPS_HAVE_SPECIAL_CCA | \ 374 (5 << CPU_MIPS_CACHED_CCA_SHIFT), "SB1" }, 375 376 { 0, 0, 0, 0, 64, 377 0, NULL } 378 }; 379 380 static const struct pridtab fputab[] = { 381 { 0, MIPS_SOFT, -1, 0, 0, 0, "software emulated floating point" }, 382 { 0, MIPS_R2360, -1, 0, 0, 0, "MIPS R2360 Floating Point Board" }, 383 { 0, MIPS_R2010, -1, 0, 0, 0, "MIPS R2010 FPC" }, 384 { 0, MIPS_R3010, -1, 0, 0, 0, "MIPS R3010 FPC" }, 385 { 0, MIPS_R6010, -1, 0, 0, 0, "MIPS R6010 FPC" }, 386 { 0, MIPS_R4010, -1, 0, 0, 0, "MIPS R4010 FPC" }, 387 { 0, MIPS_R10000, -1, 0, 0, 0, "built-in FPU" }, 388 }; 389 390 /* 391 * Company ID's are not sparse (yet), this array is indexed directly 392 * by pridtab->cpu_cid. 393 */ 394 static const char *cidnames[] = { 395 "Prehistoric", 396 "MIPS", /* or "MIPS Technologies, Inc. */ 397 "Broadcom", /* or "Broadcom Corp." */ 398 "Alchemy", /* or "Alchemy Semiconductor" */ 399 "SiByte", /* or "Broadcom Corp. (SiByte)" */ 400 "SandCraft", 401 }; 402 #define ncidnames (sizeof(cidnames) / sizeof(cidnames[0])) 403 404 #ifdef MIPS1 405 /* 406 * MIPS-I locore function vector 407 */ 408 static const mips_locore_jumpvec_t mips1_locore_vec = 409 { 410 mips1_SetPID, 411 mips1_TBIAP, 412 mips1_TBIS, 413 mips1_TLBUpdate, 414 mips1_wbflush, 415 }; 416 417 static void 418 mips1_vector_init(void) 419 { 420 extern char mips1_UTLBMiss[], mips1_UTLBMissEnd[]; 421 extern char mips1_exception[], mips1_exceptionEnd[]; 422 423 /* 424 * Copy down exception vector code. 425 */ 426 if (mips1_UTLBMissEnd - mips1_UTLBMiss > 0x80) 427 panic("startup: UTLB vector code too large"); 428 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips1_UTLBMiss, 429 mips1_UTLBMissEnd - mips1_UTLBMiss); 430 431 if (mips1_exceptionEnd - mips1_exception > 0x80) 432 panic("startup: general exception vector code too large"); 433 memcpy((void *)MIPS1_GEN_EXC_VEC, mips1_exception, 434 mips1_exceptionEnd - mips1_exception); 435 436 /* 437 * Copy locore-function vector. 438 */ 439 memcpy(&mips_locore_jumpvec, &mips1_locore_vec, 440 sizeof(mips_locore_jumpvec_t)); 441 442 /* 443 * Clear out the I and D caches. 444 */ 445 mips_icache_sync_all(); 446 mips_dcache_wbinv_all(); 447 } 448 #endif /* MIPS1 */ 449 450 #if defined(MIPS3) 451 #ifndef MIPS3_5900 /* XXX */ 452 /* 453 * MIPS III locore function vector 454 */ 455 static const mips_locore_jumpvec_t mips3_locore_vec = 456 { 457 mips3_SetPID, 458 mips3_TBIAP, 459 mips3_TBIS, 460 mips3_TLBUpdate, 461 mips3_wbflush, 462 }; 463 464 static void 465 mips3_vector_init(void) 466 { 467 /* r4000 exception handler address and end */ 468 extern char mips3_exception[], mips3_exceptionEnd[]; 469 470 /* TLB miss handler address and end */ 471 extern char mips3_TLBMiss[], mips3_TLBMissEnd[]; 472 extern char mips3_XTLBMiss[], mips3_XTLBMissEnd[]; 473 474 /* Cache error handler */ 475 extern char mips3_cache[], mips3_cacheEnd[]; 476 477 /* 478 * Copy down exception vector code. 479 */ 480 481 if (mips3_TLBMissEnd - mips3_TLBMiss > 0x80) 482 panic("startup: UTLB vector code too large"); 483 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips3_TLBMiss, 484 mips3_TLBMissEnd - mips3_TLBMiss); 485 486 if (mips3_XTLBMissEnd - mips3_XTLBMiss > 0x80) 487 panic("startup: XTLB vector code too large"); 488 memcpy((void *)MIPS3_XTLB_MISS_EXC_VEC, mips3_XTLBMiss, 489 mips3_XTLBMissEnd - mips3_XTLBMiss); 490 491 if (mips3_cacheEnd - mips3_cache > 0x80) 492 panic("startup: Cache error vector code too large"); 493 memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips3_cache, 494 mips3_cacheEnd - mips3_cache); 495 496 if (mips3_exceptionEnd - mips3_exception > 0x80) 497 panic("startup: General exception vector code too large"); 498 memcpy((void *)MIPS3_GEN_EXC_VEC, mips3_exception, 499 mips3_exceptionEnd - mips3_exception); 500 501 /* 502 * Copy locore-function vector. 503 */ 504 memcpy(&mips_locore_jumpvec, &mips3_locore_vec, 505 sizeof(mips_locore_jumpvec_t)); 506 507 mips_icache_sync_all(); 508 mips_dcache_wbinv_all(); 509 510 /* Clear BEV in SR so we start handling our own exceptions */ 511 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV); 512 } 513 #endif /* !MIPS3_5900 */ 514 515 #ifdef MIPS3_5900 /* XXX */ 516 /* 517 * MIPS R5900 locore function vector. 518 * Same as MIPS32 - all MMU registers are 32bit. 519 */ 520 static const mips_locore_jumpvec_t r5900_locore_vec = 521 { 522 mips5900_SetPID, 523 mips5900_TBIAP, 524 mips5900_TBIS, 525 mips5900_TLBUpdate, 526 mips5900_wbflush, 527 }; 528 529 static void 530 r5900_vector_init(void) 531 { 532 extern char mips5900_exception[], mips5900_exceptionEnd[]; 533 extern char mips5900_TLBMiss[], mips5900_TLBMissEnd[]; 534 size_t esz = mips5900_exceptionEnd - mips5900_exception; 535 size_t tsz = mips5900_TLBMissEnd - mips5900_TLBMiss; 536 537 KDASSERT(tsz <= 0x80); 538 KDASSERT(esz <= 0x80); 539 540 if (tsz > 0x80) 541 panic("startup: UTLB vector code too large"); 542 if (esz > 0x80) 543 panic("startup: General exception vector code too large"); 544 545 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips5900_TLBMiss, tsz); 546 memcpy((void *)MIPS_R5900_COUNTER_EXC_VEC, mips5900_exception, esz); 547 memcpy((void *)MIPS_R5900_DEBUG_EXC_VEC, mips5900_exception, esz); 548 memcpy((void *)MIPS3_GEN_EXC_VEC, mips5900_exception, esz); 549 memcpy((void *)MIPS3_INTR_EXC_VEC, mips5900_exception, esz); 550 551 memcpy(&mips_locore_jumpvec, &r5900_locore_vec, 552 sizeof(mips_locore_jumpvec_t)); 553 554 mips_config_cache(); 555 556 mips_icache_sync_all(); 557 mips_dcache_wbinv_all(); 558 559 /* Clear BEV in SR so we start handling our own exceptions */ 560 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV); 561 } 562 #endif /* MIPS3_5900 */ 563 #endif /* MIPS3 */ 564 565 #ifdef MIPS32 566 /* 567 * MIPS32 locore function vector 568 */ 569 static const mips_locore_jumpvec_t mips32_locore_vec = 570 { 571 mips32_SetPID, 572 mips32_TBIAP, 573 mips32_TBIS, 574 mips32_TLBUpdate, 575 mips32_wbflush, 576 }; 577 578 static void 579 mips32_vector_init(void) 580 { 581 /* r4000 exception handler address and end */ 582 extern char mips32_exception[], mips32_exceptionEnd[]; 583 584 /* TLB miss handler address and end */ 585 extern char mips32_TLBMiss[], mips32_TLBMissEnd[]; 586 587 /* Cache error handler */ 588 extern char mips32_cache[], mips32_cacheEnd[]; 589 590 /* MIPS32/MIPS64 interrupt exception handler */ 591 extern char mips32_intr[], mips32_intrEnd[]; 592 593 /* 594 * Copy down exception vector code. 595 */ 596 597 if (mips32_TLBMissEnd - mips32_TLBMiss > 0x80) 598 panic("startup: UTLB vector code too large"); 599 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips32_TLBMiss, 600 mips32_TLBMissEnd - mips32_TLBMiss); 601 602 if (mips32_cacheEnd - mips32_cache > 0x80) 603 panic("startup: Cache error vector code too large"); 604 memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips32_cache, 605 mips32_cacheEnd - mips32_cache); 606 607 if (mips32_exceptionEnd - mips32_exception > 0x80) 608 panic("startup: General exception vector code too large"); 609 memcpy((void *)MIPS3_GEN_EXC_VEC, mips32_exception, 610 mips32_exceptionEnd - mips32_exception); 611 612 if (mips32_intrEnd - mips32_intr > 0x80) 613 panic("startup: interrupt exception vector code too large"); 614 #if 0 /* XXX - why doesn't mipsNN_intr() work? */ 615 memcpy((void *)MIPS3_INTR_EXC_VEC, mips32_intr, 616 mips32_intrEnd - mips32_intr); 617 #else 618 memcpy((void *)MIPS3_INTR_EXC_VEC, mips32_exception, 619 mips32_exceptionEnd - mips32_exception); 620 #endif 621 622 /* 623 * Copy locore-function vector. 624 */ 625 memcpy(&mips_locore_jumpvec, &mips32_locore_vec, 626 sizeof(mips_locore_jumpvec_t)); 627 628 mips_icache_sync_all(); 629 mips_dcache_wbinv_all(); 630 631 /* Clear BEV in SR so we start handling our own exceptions */ 632 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV); 633 } 634 #endif /* MIPS32 */ 635 636 #ifdef MIPS64 637 /* 638 * MIPS64 locore function vector 639 */ 640 const mips_locore_jumpvec_t mips64_locore_vec = 641 { 642 mips64_SetPID, 643 mips64_TBIAP, 644 mips64_TBIS, 645 mips64_TLBUpdate, 646 mips64_wbflush, 647 }; 648 649 static void 650 mips64_vector_init(void) 651 { 652 /* r4000 exception handler address and end */ 653 extern char mips64_exception[], mips64_exceptionEnd[]; 654 655 /* TLB miss handler address and end */ 656 extern char mips64_TLBMiss[], mips64_TLBMissEnd[]; 657 extern char mips64_XTLBMiss[], mips64_XTLBMissEnd[]; 658 659 /* Cache error handler */ 660 extern char mips64_cache[], mips64_cacheEnd[]; 661 662 /* MIPS32/MIPS64 interrupt exception handler */ 663 extern char mips64_intr[], mips64_intrEnd[]; 664 665 /* 666 * Copy down exception vector code. 667 */ 668 669 if (mips64_TLBMissEnd - mips64_TLBMiss > 0x80) 670 panic("startup: UTLB vector code too large"); 671 memcpy((void *)MIPS_UTLB_MISS_EXC_VEC, mips64_TLBMiss, 672 mips64_TLBMissEnd - mips64_TLBMiss); 673 674 if (mips64_XTLBMissEnd - mips64_XTLBMiss > 0x80) 675 panic("startup: XTLB vector code too large"); 676 memcpy((void *)MIPS3_XTLB_MISS_EXC_VEC, mips64_XTLBMiss, 677 mips64_XTLBMissEnd - mips64_XTLBMiss); 678 679 if (mips64_cacheEnd - mips64_cache > 0x80) 680 panic("startup: Cache error vector code too large"); 681 memcpy((void *)MIPS3_CACHE_ERR_EXC_VEC, mips64_cache, 682 mips64_cacheEnd - mips64_cache); 683 684 if (mips64_exceptionEnd - mips64_exception > 0x80) 685 panic("startup: General exception vector code too large"); 686 memcpy((void *)MIPS3_GEN_EXC_VEC, mips64_exception, 687 mips64_exceptionEnd - mips64_exception); 688 689 if (mips64_intrEnd - mips64_intr > 0x80) 690 panic("startup: interrupt exception vector code too large"); 691 #if 0 /* XXX - why doesn't mipsNN_intr() work? */ 692 memcpy((void *)MIPS3_INTR_EXC_VEC, mips64_intr, 693 mips64_intrEnd - mips64_intr); 694 #else 695 memcpy((void *)MIPS3_INTR_EXC_VEC, mips64_exception, 696 mips64_exceptionEnd - mips64_exception); 697 #endif 698 699 /* 700 * Copy locore-function vector. 701 */ 702 memcpy(&mips_locore_jumpvec, &mips64_locore_vec, 703 sizeof(mips_locore_jumpvec_t)); 704 705 mips_icache_sync_all(); 706 mips_dcache_wbinv_all(); 707 708 /* Clear BEV in SR so we start handling our own exceptions */ 709 mips_cp0_status_write(mips_cp0_status_read() & ~MIPS3_SR_DIAG_BEV); 710 } 711 #endif /* MIPS64 */ 712 713 /* 714 * Do all the stuff that locore normally does before calling main(), 715 * that is common to all mips-CPU NetBSD ports. 716 * 717 * The principal purpose of this function is to examine the 718 * variable cpu_id, into which the kernel locore start code 719 * writes the cpu ID register, and to then copy appropriate 720 * code into the CPU exception-vector entries and the jump tables 721 * used to hide the differences in cache and TLB handling in 722 * different MIPS CPUs. 723 * 724 * This should be the very first thing called by each port's 725 * init_main() function. 726 */ 727 728 /* 729 * Initialize the hardware exception vectors, and the jump table used to 730 * call locore cache and TLB management functions, based on the kind 731 * of CPU the kernel is running on. 732 */ 733 void 734 mips_vector_init(void) 735 { 736 const struct pridtab *ct; 737 738 mycpu = NULL; 739 for (ct = cputab; ct->cpu_name != NULL; ct++) { 740 if (MIPS_PRID_CID(cpu_id) != ct->cpu_cid || 741 MIPS_PRID_IMPL(cpu_id) != ct->cpu_pid) 742 continue; 743 if (ct->cpu_rev >= 0 && 744 MIPS_PRID_REV(cpu_id) != ct->cpu_rev) 745 continue; 746 747 mycpu = ct; 748 cpu_arch = ct->cpu_isa; 749 mips_num_tlb_entries = ct->cpu_ntlb; 750 751 break; 752 } 753 754 if (mycpu == NULL) 755 panic("CPU type (0x%x) not supported", cpu_id); 756 757 #if defined(MIPS32) || defined(MIPS64) 758 if (MIPS_PRID_CID(cpu_id) != 0) { 759 /* MIPS32/MIPS64, use coprocessor 0 config registers */ 760 uint32_t cfg, cfg1; 761 762 cfg = mips3_cp0_config_read(); 763 cfg1 = mipsNN_cp0_config1_read(); 764 765 /* pick CPU type */ 766 switch (MIPSNN_GET(CFG_AT, cfg)) { 767 case MIPSNN_CFG_AT_MIPS32: 768 cpu_arch = CPU_ARCH_MIPS32; 769 break; 770 case MIPSNN_CFG_AT_MIPS64: 771 cpu_arch = CPU_ARCH_MIPS64; 772 break; 773 case MIPSNN_CFG_AT_MIPS64S: 774 default: 775 panic("MIPS32/64 architecture type %d not supported", 776 MIPSNN_GET(CFG_AT, cfg)); 777 } 778 779 if (MIPSNN_GET(CFG_AR, cfg) != MIPSNN_CFG_AR_REV1) 780 printf("WARNING: MIPS32/64 arch revision != revision 1!\n"); 781 782 /* figure out MMU type (and number of TLB entries) */ 783 switch (MIPSNN_GET(CFG_MT, cfg)) { 784 case MIPSNN_CFG_MT_TLB: 785 mips_num_tlb_entries = MIPSNN_CFG1_MS(cfg1); 786 break; 787 case MIPSNN_CFG_MT_NONE: 788 case MIPSNN_CFG_MT_BAT: 789 case MIPSNN_CFG_MT_FIXED: 790 default: 791 panic("MIPS32/64 MMU type %d not supported", 792 MIPSNN_GET(CFG_MT, cfg)); 793 } 794 } 795 #endif /* defined(MIPS32) || defined(MIPS64) */ 796 797 if (cpu_arch < 1) 798 panic("Unknown CPU ISA for CPU type 0x%x\n", cpu_id); 799 if (mips_num_tlb_entries < 1) 800 panic("Unknown number of TLBs for CPU type 0x%x\n", cpu_id); 801 802 /* 803 * Check cpu-specific flags. 804 */ 805 mips_cpu_flags = mycpu->cpu_flags; 806 mips_has_r4k_mmu = mips_cpu_flags & CPU_MIPS_R4K_MMU; 807 mips_has_llsc = !(mips_cpu_flags & CPU_MIPS_NO_LLSC); 808 809 if (mycpu->cpu_flags & CPU_MIPS_HAVE_SPECIAL_CCA) { 810 uint32_t cca; 811 812 cca = (ct->cpu_flags & CPU_MIPS_CACHED_CCA_MASK) >> 813 CPU_MIPS_CACHED_CCA_SHIFT; 814 mips3_pg_cached = MIPS3_CCA_TO_PG(cca); 815 } else 816 mips3_pg_cached = MIPS3_DEFAULT_PG_CACHED; 817 818 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG 819 mips_machdep_cache_config(); 820 #endif 821 822 /* 823 * Determine cache configuration and initialize our cache 824 * frobbing routine function pointers. 825 */ 826 mips_config_cache(); 827 828 /* 829 * Now initialize our ISA-dependent function vector. 830 */ 831 switch (cpu_arch) { 832 #ifdef MIPS1 833 case CPU_ARCH_MIPS1: 834 mips1_TBIA(mips_num_tlb_entries); 835 mips1_vector_init(); 836 memcpy(mips_locoresw, mips1_locoresw, sizeof(mips_locoresw)); 837 break; 838 #endif 839 #if defined(MIPS3) 840 case CPU_ARCH_MIPS3: 841 case CPU_ARCH_MIPS4: 842 #ifdef MIPS3_5900 /* XXX */ 843 mips3_cp0_wired_write(0); 844 mips5900_TBIA(mips_num_tlb_entries); 845 mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES); 846 r5900_vector_init(); 847 memcpy(mips_locoresw, mips5900_locoresw, sizeof(mips_locoresw)); 848 #else /* MIPS3_5900 */ 849 mips3_cp0_wired_write(0); 850 mips3_TBIA(mips_num_tlb_entries); 851 mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES); 852 mips3_vector_init(); 853 memcpy(mips_locoresw, mips3_locoresw, sizeof(mips_locoresw)); 854 #endif /* MIPS3_5900 */ 855 break; 856 #endif 857 #ifdef MIPS32 858 case CPU_ARCH_MIPS32: 859 mips3_cp0_wired_write(0); 860 mips32_TBIA(mips_num_tlb_entries); 861 mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES); 862 mips32_vector_init(); 863 memcpy(mips_locoresw, mips32_locoresw, sizeof(mips_locoresw)); 864 break; 865 #endif 866 #if defined(MIPS64) 867 case CPU_ARCH_MIPS64: 868 mips3_cp0_wired_write(0); 869 mips64_TBIA(mips_num_tlb_entries); 870 mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES); 871 mips64_vector_init(); 872 memcpy(mips_locoresw, mips64_locoresw, sizeof(mips_locoresw)); 873 break; 874 #endif 875 default: 876 printf("cpu_arch 0x%x: not supported\n", cpu_arch); 877 cpu_reboot(RB_HALT, NULL); 878 } 879 880 /* 881 * Install power-saving idle routines. 882 */ 883 switch (MIPS_PRID_CID(cpu_id)) { 884 case MIPS_PRID_CID_PREHISTORIC: 885 switch (MIPS_PRID_IMPL(cpu_id)) { 886 #if defined(MIPS3) && !defined(MIPS3_5900) 887 case MIPS_RM5200: 888 case MIPS_RM7000: 889 { 890 void rm52xx_idle(void); 891 892 CPU_IDLE = (long *) rm52xx_idle; 893 break; 894 } 895 #endif /* MIPS3 && !MIPS3_5900 */ 896 default: 897 /* Nothing. */ 898 break; 899 } 900 #if defined(MIPS32) || defined(MIPS64) 901 default: 902 { 903 /* 904 * XXX: wait is valid on all mips32/64, but do we 905 * always want to use it? 906 */ 907 void mipsNN_idle(void); 908 909 CPU_IDLE = (long *) mipsNN_idle; 910 } 911 #endif 912 } 913 } 914 915 void 916 mips_set_wbflush(flush_fn) 917 void (*flush_fn)(void); 918 { 919 #undef wbflush 920 mips_locore_jumpvec.wbflush = flush_fn; 921 (*flush_fn)(); 922 } 923 924 /* 925 * Identify product revision IDs of cpu and fpu. 926 */ 927 void 928 cpu_identify(void) 929 { 930 static const char * const waynames[] = { 931 "fully set-associative", /* 0 */ 932 "direct-mapped", /* 1 */ 933 "2-way set-associative", /* 2 */ 934 NULL, /* 3 */ 935 "4-way set-associative", /* 4 */ 936 }; 937 #define nwaynames (sizeof(waynames) / sizeof(waynames[0])) 938 static const char * const wtnames[] = { 939 "write-back", 940 "write-through", 941 }; 942 static const char * const label = "cpu0"; /* XXX */ 943 char *cpuname, *fpuname; 944 int i; 945 946 cpuname = mycpu->cpu_name; 947 948 fpuname = NULL; 949 for (i = 0; i < sizeof(fputab)/sizeof(fputab[0]); i++) { 950 if (MIPS_PRID_CID(fpu_id) == fputab[i].cpu_cid && 951 MIPS_PRID_IMPL(fpu_id) == fputab[i].cpu_pid) { 952 fpuname = fputab[i].cpu_name; 953 break; 954 } 955 } 956 if (fpuname == NULL && MIPS_PRID_IMPL(fpu_id) == MIPS_PRID_IMPL(cpu_id)) 957 fpuname = "built-in FPU"; 958 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4700) /* FPU PRid is 0x20 */ 959 fpuname = "built-in FPU"; 960 if (MIPS_PRID_IMPL(cpu_id) == MIPS_RC64470) /* FPU PRid is 0x21 */ 961 fpuname = "built-in FPU"; 962 963 if (mycpu->cpu_cid != 0) { 964 if (mycpu->cpu_cid <= ncidnames) 965 printf("%s ", cidnames[mycpu->cpu_cid]); 966 else { 967 printf("Unknown Company ID - 0x%x", mycpu->cpu_cid); 968 printf("%s: ", label); 969 } 970 } 971 if (cpuname != NULL) 972 printf("%s (0x%x)", cpuname, cpu_id); 973 else 974 printf("unknown CPU type (0x%x)", cpu_id); 975 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) 976 printf(" Rev. %d.%d", MIPS_PRID_REV_MAJ(cpu_id), 977 MIPS_PRID_REV_MIN(cpu_id)); 978 else 979 printf(" Rev. %d", MIPS_PRID_REV(cpu_id)); 980 981 if (fpuname != NULL) 982 printf(" with %s", fpuname); 983 else 984 printf(" with unknown FPC type (0x%x)", fpu_id); 985 if (fpu_id != 0) { 986 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) 987 printf(" Rev. %d.%d", MIPS_PRID_REV_MAJ(fpu_id), 988 MIPS_PRID_REV_MIN(fpu_id)); 989 else 990 printf(" Rev. %d", MIPS_PRID_REV(fpu_id)); 991 } 992 printf("\n"); 993 994 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC && 995 MIPS_PRID_RSVD(cpu_id) != 0) { 996 printf("%s: NOTE: top 8 bits of prehistoric PRID not 0!\n", 997 label); 998 printf("%s: Please mail port-mips@netbsd.org with cpu0 " 999 "dmesg lines.\n", label); 1000 } 1001 1002 KASSERT(mips_picache_ways < nwaynames); 1003 KASSERT(mips_pdcache_ways < nwaynames); 1004 KASSERT(mips_sicache_ways < nwaynames); 1005 KASSERT(mips_sdcache_ways < nwaynames); 1006 1007 switch (cpu_arch) { 1008 #ifdef MIPS1 1009 case CPU_ARCH_MIPS1: 1010 if (mips_picache_size) 1011 printf("%s: %dKB/%dB %s Instruction cache, " 1012 "%d TLB entries\n", label, mips_picache_size / 1024, 1013 mips_picache_line_size, waynames[mips_picache_ways], 1014 mips_num_tlb_entries); 1015 else 1016 printf("%s: %d TLB entries\n", label, 1017 mips_num_tlb_entries); 1018 if (mips_pdcache_size) 1019 printf("%s: %dKB/%dB %s %s Data cache\n", label, 1020 mips_pdcache_size / 1024, mips_pdcache_line_size, 1021 waynames[mips_pdcache_ways], 1022 wtnames[mips_pdcache_write_through]); 1023 break; 1024 #endif /* MIPS1 */ 1025 #if defined(MIPS3) || defined(MIPS32) || defined(MIPS64) 1026 case CPU_ARCH_MIPS3: 1027 case CPU_ARCH_MIPS4: 1028 case CPU_ARCH_MIPS32: 1029 case CPU_ARCH_MIPS64: 1030 if (mips_picache_size) 1031 printf("%s: %dKB/%dB %s L1 Instruction cache, " 1032 "%d TLB entries\n", label, mips_picache_size / 1024, 1033 mips_picache_line_size, waynames[mips_picache_ways], 1034 mips_num_tlb_entries); 1035 else 1036 printf("%s: %d TLB entries\n", label, mips_num_tlb_entries); 1037 if (mips_pdcache_size) 1038 printf("%s: %dKB/%dB %s %s L1 Data cache\n", label, 1039 mips_pdcache_size / 1024, mips_pdcache_line_size, 1040 waynames[mips_pdcache_ways], 1041 wtnames[mips_pdcache_write_through]); 1042 if (mips_sdcache_line_size) 1043 printf("%s: %dKB/%dB %s %s L2 %s cache\n", label, 1044 mips_sdcache_size / 1024, mips_sdcache_line_size, 1045 waynames[mips_sdcache_ways], 1046 wtnames[mips_sdcache_write_through], 1047 mips_scache_unified ? "Unified" : "Data"); 1048 break; 1049 #endif /* MIPS3 */ 1050 default: 1051 panic("cpu_identify: impossible"); 1052 } 1053 } 1054 1055 /* 1056 * Set registers on exec. 1057 * Clear all registers except sp, pc, and t9. 1058 * $sp is set to the stack pointer passed in. $pc is set to the entry 1059 * point given by the exec_package passed in, as is $t9 (used for PIC 1060 * code by the MIPS elf abi). 1061 */ 1062 void 1063 setregs(p, pack, stack) 1064 struct proc *p; 1065 struct exec_package *pack; 1066 u_long stack; 1067 { 1068 struct frame *f = (struct frame *)p->p_md.md_regs; 1069 1070 memset(f, 0, sizeof(struct frame)); 1071 f->f_regs[SP] = (int) stack; 1072 f->f_regs[PC] = (int) pack->ep_entry & ~3; 1073 f->f_regs[T9] = (int) pack->ep_entry & ~3; /* abicall requirement */ 1074 f->f_regs[SR] = PSL_USERSET; 1075 /* 1076 * Set up arguments for the rtld-capable crt0: 1077 * a0 stack pointer 1078 * a1 rtld cleanup (filled in by dynamic loader) 1079 * a2 rtld object (filled in by dynamic loader) 1080 * a3 ps_strings 1081 */ 1082 f->f_regs[A0] = (int) stack; 1083 f->f_regs[A1] = 0; 1084 f->f_regs[A2] = 0; 1085 f->f_regs[A3] = (int)p->p_psstr; 1086 1087 if ((p->p_md.md_flags & MDP_FPUSED) && p == fpcurproc) 1088 fpcurproc = (struct proc *)0; 1089 memset(&p->p_addr->u_pcb.pcb_fpregs, 0, sizeof(struct fpreg)); 1090 p->p_md.md_flags &= ~MDP_FPUSED; 1091 p->p_md.md_ss_addr = 0; 1092 } 1093 1094 /* 1095 * WARNING: code in locore.s assumes the layout shown for sf_signum 1096 * thru sf_handler so... don't screw with them! 1097 */ 1098 struct sigframe { 1099 int sf_signum; /* signo for handler */ 1100 int sf_code; /* additional info for handler */ 1101 struct sigcontext *sf_scp; /* context ptr for handler */ 1102 sig_t sf_handler; /* handler addr for u_sigc */ 1103 struct sigcontext sf_sc; /* actual context */ 1104 }; 1105 1106 #ifdef DEBUG 1107 int sigdebug = 0; 1108 int sigpid = 0; 1109 #define SDB_FOLLOW 0x01 1110 #define SDB_KSTACK 0x02 1111 #define SDB_FPSTATE 0x04 1112 #endif 1113 1114 /* 1115 * Send an interrupt to process. 1116 */ 1117 void 1118 sendsig(catcher, sig, mask, code) 1119 sig_t catcher; 1120 int sig; 1121 sigset_t *mask; 1122 u_long code; 1123 { 1124 struct proc *p = curproc; 1125 struct sigframe *fp; 1126 struct frame *f; 1127 int onstack; 1128 struct sigcontext ksc; 1129 1130 f = (struct frame *)p->p_md.md_regs; 1131 1132 /* Do we need to jump onto the signal stack? */ 1133 onstack = 1134 (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 1135 (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; 1136 1137 /* Allocate space for the signal handler context. */ 1138 if (onstack) 1139 fp = (struct sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp + 1140 p->p_sigctx.ps_sigstk.ss_size); 1141 else 1142 /* cast for _MIPS_BSD_API == _MIPS_BSD_API_LP32_64CLEAN case */ 1143 fp = (struct sigframe *)(u_int32_t)f->f_regs[SP]; 1144 fp--; 1145 1146 #ifdef DEBUG 1147 if ((sigdebug & SDB_FOLLOW) || 1148 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 1149 printf("sendsig(%d): sig %d ssp %p usp %p scp %p\n", 1150 p->p_pid, sig, &onstack, fp, &fp->sf_sc); 1151 #endif 1152 1153 /* Build stack frame for signal trampoline. */ 1154 ksc.sc_pc = f->f_regs[PC]; 1155 ksc.mullo = f->f_regs[MULLO]; 1156 ksc.mulhi = f->f_regs[MULHI]; 1157 1158 /* Save register context. */ 1159 ksc.sc_regs[ZERO] = 0xACEDBADE; /* magic number */ 1160 memcpy(&ksc.sc_regs[1], &f->f_regs[1], 1161 sizeof(ksc.sc_regs) - sizeof(ksc.sc_regs[0])); 1162 1163 /* Save the floating-pointstate, if necessary, then copy it. */ 1164 #ifndef SOFTFLOAT 1165 ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED; 1166 if (ksc.sc_fpused) { 1167 /* if FPU has current state, save it first */ 1168 if (p == fpcurproc) 1169 savefpregs(p); 1170 *(struct fpreg *)ksc.sc_fpregs = p->p_addr->u_pcb.pcb_fpregs; 1171 } 1172 #else 1173 *(struct fpreg *)ksc.sc_fpregs = p->p_addr->u_pcb.pcb_fpregs; 1174 #endif 1175 1176 /* Save signal stack. */ 1177 ksc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; 1178 1179 /* Save signal mask. */ 1180 ksc.sc_mask = *mask; 1181 1182 #if defined(COMPAT_13) || defined(COMPAT_ULTRIX) 1183 /* 1184 * XXX We always have to save an old style signal mask because 1185 * XXX we might be delivering a signal to a process which will 1186 * XXX escape from the signal in a non-standard way and invoke 1187 * XXX sigreturn() directly. 1188 */ 1189 native_sigset_to_sigset13(mask, &ksc.__sc_mask13); 1190 #endif 1191 1192 if (copyout(&ksc, &fp->sf_sc, sizeof(ksc))) { 1193 /* 1194 * Process has trashed its stack; give it an illegal 1195 * instruction to halt it in its tracks. 1196 */ 1197 #ifdef DEBUG 1198 if ((sigdebug & SDB_FOLLOW) || 1199 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 1200 printf("sendsig(%d): copyout failed on sig %d\n", 1201 p->p_pid, sig); 1202 #endif 1203 sigexit(p, SIGILL); 1204 /* NOTREACHED */ 1205 } 1206 1207 /* Set up the registers to return to sigcode. */ 1208 f->f_regs[A0] = sig; 1209 f->f_regs[A1] = code; 1210 f->f_regs[A2] = (int)&fp->sf_sc; 1211 f->f_regs[A3] = (int)catcher; 1212 1213 f->f_regs[PC] = (int)catcher; 1214 f->f_regs[T9] = (int)catcher; 1215 f->f_regs[SP] = (int)fp; 1216 1217 /* Signal trampoline code is at base of user stack. */ 1218 f->f_regs[RA] = (int)p->p_sigctx.ps_sigcode; 1219 1220 /* Remember that we're now on the signal stack. */ 1221 if (onstack) 1222 p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 1223 1224 #ifdef DEBUG 1225 if ((sigdebug & SDB_FOLLOW) || 1226 ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) 1227 printf("sendsig(%d): sig %d returns\n", 1228 p->p_pid, sig); 1229 #endif 1230 } 1231 1232 /* 1233 * System call to cleanup state after a signal 1234 * has been taken. Reset signal mask and 1235 * stack state from context left by sendsig (above). 1236 * Return to previous pc and psl as specified by 1237 * context left by sendsig. Check carefully to 1238 * make sure that the user has not modified the 1239 * psl to gain improper privileges or to cause 1240 * a machine fault. 1241 */ 1242 /* ARGSUSED */ 1243 int 1244 sys___sigreturn14(p, v, retval) 1245 struct proc *p; 1246 void *v; 1247 register_t *retval; 1248 { 1249 struct sys___sigreturn14_args /* { 1250 syscallarg(struct sigcontext *) sigcntxp; 1251 } */ *uap = v; 1252 struct sigcontext *scp, ksc; 1253 struct frame *f; 1254 int error; 1255 1256 /* 1257 * The trampoline code hands us the context. 1258 * It is unsafe to keep track of it ourselves, in the event that a 1259 * program jumps out of a signal handler. 1260 */ 1261 scp = SCARG(uap, sigcntxp); 1262 #ifdef DEBUG 1263 if (sigdebug & SDB_FOLLOW) 1264 printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); 1265 #endif 1266 if ((error = copyin(scp, &ksc, sizeof(ksc))) != 0) 1267 return (error); 1268 1269 if ((int) ksc.sc_regs[ZERO] != 0xACEDBADE) /* magic number */ 1270 return (EINVAL); 1271 1272 /* Restore the register context. */ 1273 f = (struct frame *)p->p_md.md_regs; 1274 f->f_regs[PC] = ksc.sc_pc; 1275 f->f_regs[MULLO] = ksc.mullo; 1276 f->f_regs[MULHI] = ksc.mulhi; 1277 memcpy(&f->f_regs[1], &scp->sc_regs[1], 1278 sizeof(scp->sc_regs) - sizeof(scp->sc_regs[0])); 1279 #ifndef SOFTFLOAT 1280 if (scp->sc_fpused) { 1281 /* Disable the FPU to fault in FP registers. */ 1282 f->f_regs[SR] &= ~MIPS_SR_COP_1_BIT; 1283 if (p == fpcurproc) { 1284 fpcurproc = (struct proc *)0; 1285 } 1286 p->p_addr->u_pcb.pcb_fpregs = *(struct fpreg *)scp->sc_fpregs; 1287 } 1288 #else 1289 p->p_addr->u_pcb.pcb_fpregs = *(struct fpreg *)scp->sc_fpregs; 1290 #endif 1291 1292 /* Restore signal stack. */ 1293 if (ksc.sc_onstack & SS_ONSTACK) 1294 p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; 1295 else 1296 p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; 1297 1298 /* Restore signal mask. */ 1299 (void) sigprocmask1(p, SIG_SETMASK, &ksc.sc_mask, 0); 1300 1301 return (EJUSTRETURN); 1302 } 1303 1304 /* 1305 * These are imported from platform-specific code. 1306 * XXX Should be declared in a header file. 1307 */ 1308 extern phys_ram_seg_t mem_clusters[]; 1309 extern int mem_cluster_cnt; 1310 1311 /* 1312 * These variables are needed by /sbin/savecore. 1313 */ 1314 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 1315 int dumpsize = 0; /* pages */ 1316 long dumplo = 0; /* blocks */ 1317 1318 struct user dumppcb; /* Actually, struct pcb would do. */ 1319 1320 /* 1321 * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers. 1322 */ 1323 int 1324 cpu_dumpsize(void) 1325 { 1326 int size; 1327 1328 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) + 1329 ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t)); 1330 if (roundup(size, dbtob(1)) != dbtob(1)) 1331 return (-1); 1332 1333 return (1); 1334 } 1335 1336 /* 1337 * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped. 1338 */ 1339 u_long 1340 cpu_dump_mempagecnt(void) 1341 { 1342 u_long i, n; 1343 1344 n = 0; 1345 for (i = 0; i < mem_cluster_cnt; i++) 1346 n += atop(mem_clusters[i].size); 1347 return (n); 1348 } 1349 1350 /* 1351 * cpu_dump: dump machine-dependent kernel core dump headers. 1352 */ 1353 int 1354 cpu_dump(void) 1355 { 1356 int (*dump)(dev_t, daddr_t, caddr_t, size_t); 1357 char buf[dbtob(1)]; 1358 kcore_seg_t *segp; 1359 cpu_kcore_hdr_t *cpuhdrp; 1360 phys_ram_seg_t *memsegp; 1361 int i; 1362 1363 dump = bdevsw[major(dumpdev)].d_dump; 1364 1365 memset(buf, 0, sizeof buf); 1366 segp = (kcore_seg_t *)buf; 1367 cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))]; 1368 memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) + 1369 ALIGN(sizeof(*cpuhdrp))]; 1370 1371 /* 1372 * Generate a segment header. 1373 */ 1374 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 1375 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); 1376 1377 /* 1378 * Add the machine-dependent header info. 1379 */ 1380 if (MIPS_HAS_R4K_MMU) { 1381 cpuhdrp->archlevel = 3; 1382 cpuhdrp->pg_shift = MIPS3_PG_SHIFT; 1383 cpuhdrp->pg_frame = MIPS3_PG_FRAME; 1384 cpuhdrp->pg_v = MIPS3_PG_V; 1385 } else { 1386 cpuhdrp->archlevel = 1; 1387 cpuhdrp->pg_shift = MIPS1_PG_SHIFT; 1388 cpuhdrp->pg_frame = MIPS1_PG_FRAME; 1389 cpuhdrp->pg_v = MIPS1_PG_V; 1390 } 1391 cpuhdrp->sysmappa = MIPS_KSEG0_TO_PHYS(Sysmap); 1392 cpuhdrp->sysmapsize = Sysmapsize; 1393 cpuhdrp->nmemsegs = mem_cluster_cnt; 1394 1395 /* 1396 * Fill in the memory segment descriptors. 1397 */ 1398 for (i = 0; i < mem_cluster_cnt; i++) { 1399 memsegp[i].start = mem_clusters[i].start; 1400 memsegp[i].size = mem_clusters[i].size; 1401 } 1402 1403 return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1))); 1404 } 1405 1406 /* 1407 * This is called by main to set dumplo and dumpsize. 1408 * Dumps always skip the first CLBYTES of disk space 1409 * in case there might be a disk label stored there. 1410 * If there is extra space, put dump at the end to 1411 * reduce the chance that swapping trashes it. 1412 */ 1413 void 1414 cpu_dumpconf(void) 1415 { 1416 int nblks, dumpblks; /* size of dump area */ 1417 int maj; 1418 1419 if (dumpdev == NODEV) 1420 goto bad; 1421 maj = major(dumpdev); 1422 if (maj < 0 || maj >= nblkdev) 1423 panic("dumpconf: bad dumpdev=0x%x", dumpdev); 1424 if (bdevsw[maj].d_psize == NULL) 1425 goto bad; 1426 nblks = (*bdevsw[maj].d_psize)(dumpdev); 1427 if (nblks <= ctod(1)) 1428 goto bad; 1429 1430 dumpblks = cpu_dumpsize(); 1431 if (dumpblks < 0) 1432 goto bad; 1433 dumpblks += ctod(cpu_dump_mempagecnt()); 1434 1435 /* If dump won't fit (incl. room for possible label), punt. */ 1436 if (dumpblks > (nblks - ctod(1))) 1437 goto bad; 1438 1439 /* Put dump at end of partition */ 1440 dumplo = nblks - dumpblks; 1441 1442 /* dumpsize is in page units, and doesn't include headers. */ 1443 dumpsize = cpu_dump_mempagecnt(); 1444 return; 1445 1446 bad: 1447 dumpsize = 0; 1448 } 1449 1450 /* 1451 * Dump the kernel's image to the swap partition. 1452 */ 1453 #define BYTES_PER_DUMP NBPG 1454 1455 void 1456 dumpsys(void) 1457 { 1458 u_long totalbytesleft, bytes, i, n, memcl; 1459 u_long maddr; 1460 int psize; 1461 daddr_t blkno; 1462 int (*dump)(dev_t, daddr_t, caddr_t, size_t); 1463 int error; 1464 1465 /* Save registers. */ 1466 savectx(&dumppcb); 1467 1468 if (dumpdev == NODEV) 1469 return; 1470 1471 /* 1472 * For dumps during autoconfiguration, 1473 * if dump device has already configured... 1474 */ 1475 if (dumpsize == 0) 1476 cpu_dumpconf(); 1477 if (dumplo <= 0) { 1478 printf("\ndump to dev %u,%u not possible\n", major(dumpdev), 1479 minor(dumpdev)); 1480 return; 1481 } 1482 printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), 1483 minor(dumpdev), dumplo); 1484 1485 psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 1486 printf("dump "); 1487 if (psize == -1) { 1488 printf("area unavailable\n"); 1489 return; 1490 } 1491 1492 /* XXX should purge all outstanding keystrokes. */ 1493 1494 if ((error = cpu_dump()) != 0) 1495 goto err; 1496 1497 totalbytesleft = ptoa(cpu_dump_mempagecnt()); 1498 blkno = dumplo + cpu_dumpsize(); 1499 dump = bdevsw[major(dumpdev)].d_dump; 1500 error = 0; 1501 1502 for (memcl = 0; memcl < mem_cluster_cnt; memcl++) { 1503 maddr = mem_clusters[memcl].start; 1504 bytes = mem_clusters[memcl].size; 1505 1506 for (i = 0; i < bytes; i += n, totalbytesleft -= n) { 1507 /* Print out how many MBs we have left to go. */ 1508 if ((totalbytesleft % (1024*1024)) == 0) 1509 printf("%ld ", totalbytesleft / (1024 * 1024)); 1510 1511 /* Limit size for next transfer. */ 1512 n = bytes - i; 1513 if (n > BYTES_PER_DUMP) 1514 n = BYTES_PER_DUMP; 1515 1516 error = (*dump)(dumpdev, blkno, 1517 (caddr_t)MIPS_PHYS_TO_KSEG0(maddr), n); 1518 if (error) 1519 goto err; 1520 maddr += n; 1521 blkno += btodb(n); /* XXX? */ 1522 1523 /* XXX should look for keystrokes, to cancel. */ 1524 } 1525 } 1526 1527 err: 1528 switch (error) { 1529 1530 case ENXIO: 1531 printf("device bad\n"); 1532 break; 1533 1534 case EFAULT: 1535 printf("device not ready\n"); 1536 break; 1537 1538 case EINVAL: 1539 printf("area improper\n"); 1540 break; 1541 1542 case EIO: 1543 printf("i/o error\n"); 1544 break; 1545 1546 case EINTR: 1547 printf("aborted from console\n"); 1548 break; 1549 1550 case 0: 1551 printf("succeeded\n"); 1552 break; 1553 1554 default: 1555 printf("error %d\n", error); 1556 break; 1557 } 1558 printf("\n\n"); 1559 delay(5000000); /* 5 seconds */ 1560 } 1561 1562 void 1563 mips_init_msgbuf(void) 1564 { 1565 vsize_t sz = (vsize_t)round_page(MSGBUFSIZE); 1566 vsize_t reqsz = sz; 1567 struct vm_physseg *vps; 1568 1569 vps = &vm_physmem[vm_nphysseg - 1]; 1570 1571 /* shrink so that it'll fit in the last segment */ 1572 if ((vps->avail_end - vps->avail_start) < atop(sz)) 1573 sz = ptoa(vps->avail_end - vps->avail_start); 1574 1575 vps->end -= atop(sz); 1576 vps->avail_end -= atop(sz); 1577 msgbufaddr = (caddr_t) MIPS_PHYS_TO_KSEG0(ptoa(vps->end)); 1578 initmsgbuf(msgbufaddr, sz); 1579 1580 /* Remove the last segment if it now has no pages. */ 1581 if (vps->start == vps->end) 1582 vm_nphysseg--; 1583 1584 /* warn if the message buffer had to be shrunk */ 1585 if (sz != reqsz) 1586 printf("WARNING: %ld bytes not available for msgbuf " 1587 "in last cluster (%ld used)\n", reqsz, sz); 1588 } 1589 1590 void 1591 savefpregs(p) 1592 struct proc *p; 1593 { 1594 #ifndef NOFPU 1595 u_int32_t status, fpcsr, *fp; 1596 struct frame *f; 1597 1598 if (p == NULL) 1599 return; 1600 /* 1601 * turnoff interrupts enabling CP1 to read FPCSR register. 1602 */ 1603 __asm __volatile ( 1604 ".set noreorder ;" 1605 ".set noat ;" 1606 "mfc0 %0, $12 ;" 1607 "li $1, %2 ;" 1608 "mtc0 $1, $12 ;" 1609 "nop; nop; nop; nop ;" 1610 "cfc1 %1, $31 ;" 1611 "cfc1 %1, $31 ;" 1612 ".set reorder ;" 1613 ".set at" 1614 : "=r" (status), "=r"(fpcsr) : "i"(MIPS_SR_COP_1_BIT)); 1615 /* 1616 * this process yielded FPA. 1617 */ 1618 f = (struct frame *)p->p_md.md_regs; 1619 f->f_regs[SR] &= ~MIPS_SR_COP_1_BIT; 1620 1621 /* 1622 * save FPCSR and 32bit FP register values. 1623 */ 1624 fp = (int *)p->p_addr->u_pcb.pcb_fpregs.r_regs; 1625 fp[32] = fpcsr; 1626 __asm __volatile ( 1627 ".set noreorder ;" 1628 "swc1 $f0, 0(%0) ;" 1629 "swc1 $f1, 4(%0) ;" 1630 "swc1 $f2, 8(%0) ;" 1631 "swc1 $f3, 12(%0) ;" 1632 "swc1 $f4, 16(%0) ;" 1633 "swc1 $f5, 20(%0) ;" 1634 "swc1 $f6, 24(%0) ;" 1635 "swc1 $f7, 28(%0) ;" 1636 "swc1 $f8, 32(%0) ;" 1637 "swc1 $f9, 36(%0) ;" 1638 "swc1 $f10, 40(%0) ;" 1639 "swc1 $f11, 44(%0) ;" 1640 "swc1 $f12, 48(%0) ;" 1641 "swc1 $f13, 52(%0) ;" 1642 "swc1 $f14, 56(%0) ;" 1643 "swc1 $f15, 60(%0) ;" 1644 "swc1 $f16, 64(%0) ;" 1645 "swc1 $f17, 68(%0) ;" 1646 "swc1 $f18, 72(%0) ;" 1647 "swc1 $f19, 76(%0) ;" 1648 "swc1 $f20, 80(%0) ;" 1649 "swc1 $f21, 84(%0) ;" 1650 "swc1 $f22, 88(%0) ;" 1651 "swc1 $f23, 92(%0) ;" 1652 "swc1 $f24, 96(%0) ;" 1653 "swc1 $f25, 100(%0) ;" 1654 "swc1 $f26, 104(%0) ;" 1655 "swc1 $f27, 108(%0) ;" 1656 "swc1 $f28, 112(%0) ;" 1657 "swc1 $f29, 116(%0) ;" 1658 "swc1 $f30, 120(%0) ;" 1659 "swc1 $f31, 124(%0) ;" 1660 ".set reorder" :: "r"(fp)); 1661 /* 1662 * stop CP1, enable interrupts. 1663 */ 1664 __asm __volatile ("mtc0 %0, $12" :: "r"(status)); 1665 return; 1666 #endif 1667 } 1668 1669 void 1670 loadfpregs(p) 1671 struct proc *p; 1672 { 1673 #ifndef NOFPU 1674 u_int32_t status, *fp; 1675 struct frame *f; 1676 1677 if (p == NULL) 1678 panic("loading fpregs for NULL proc"); 1679 1680 /* 1681 * turnoff interrupts enabling CP1 to load FP registers. 1682 */ 1683 __asm __volatile( 1684 ".set noreorder ;" 1685 ".set noat ;" 1686 "mfc0 %0, $12 ;" 1687 "li $1, %1 ;" 1688 "mtc0 $1, $12 ;" 1689 "nop; nop; nop; nop ;" 1690 ".set reorder ;" 1691 ".set at" : "=r"(status) : "i"(MIPS_SR_COP_1_BIT)); 1692 1693 f = (struct frame *)p->p_md.md_regs; 1694 fp = (int *)p->p_addr->u_pcb.pcb_fpregs.r_regs; 1695 /* 1696 * load 32bit FP registers and establish processes' FP context. 1697 */ 1698 __asm __volatile( 1699 ".set noreorder ;" 1700 "lwc1 $f0, 0(%0) ;" 1701 "lwc1 $f1, 4(%0) ;" 1702 "lwc1 $f2, 8(%0) ;" 1703 "lwc1 $f3, 12(%0) ;" 1704 "lwc1 $f4, 16(%0) ;" 1705 "lwc1 $f5, 20(%0) ;" 1706 "lwc1 $f6, 24(%0) ;" 1707 "lwc1 $f7, 28(%0) ;" 1708 "lwc1 $f8, 32(%0) ;" 1709 "lwc1 $f9, 36(%0) ;" 1710 "lwc1 $f10, 40(%0) ;" 1711 "lwc1 $f11, 44(%0) ;" 1712 "lwc1 $f12, 48(%0) ;" 1713 "lwc1 $f13, 52(%0) ;" 1714 "lwc1 $f14, 56(%0) ;" 1715 "lwc1 $f15, 60(%0) ;" 1716 "lwc1 $f16, 64(%0) ;" 1717 "lwc1 $f17, 68(%0) ;" 1718 "lwc1 $f18, 72(%0) ;" 1719 "lwc1 $f19, 76(%0) ;" 1720 "lwc1 $f20, 80(%0) ;" 1721 "lwc1 $f21, 84(%0) ;" 1722 "lwc1 $f22, 88(%0) ;" 1723 "lwc1 $f23, 92(%0) ;" 1724 "lwc1 $f24, 96(%0) ;" 1725 "lwc1 $f25, 100(%0) ;" 1726 "lwc1 $f26, 104(%0) ;" 1727 "lwc1 $f27, 108(%0) ;" 1728 "lwc1 $f28, 112(%0) ;" 1729 "lwc1 $f29, 116(%0) ;" 1730 "lwc1 $f30, 120(%0) ;" 1731 "lwc1 $f31, 124(%0) ;" 1732 ".set reorder" :: "r"(fp)); 1733 /* 1734 * load FPCSR and stop CP1 again while enabling interrupts. 1735 */ 1736 __asm __volatile( 1737 ".set noreorder ;" 1738 ".set noat ;" 1739 "ctc1 %0, $31 ;" 1740 "mtc0 %1, $12 ;" 1741 ".set reorder ;" 1742 ".set at" 1743 :: "r"(fp[32] &~ MIPS_FPU_EXCEPTION_BITS), "r"(status)); 1744 return; 1745 #endif 1746 } 1747