1/* $NetBSD: mipsX_subr.S,v 1.2 2002/03/11 16:39:40 uch 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 (c) 1997 Jonathan Stone (hereinafter referred to as the author) 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by Jonathan R. Stone for 53 * the NetBSD Project. 54 * 4. The name of the author may not be used to endorse or promote products 55 * derived from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * SUCH DAMAGE. 68 */ 69 70/* 71 * Copyright (c) 1992, 1993 72 * The Regents of the University of California. All rights reserved. 73 * 74 * This code is derived from software contributed to Berkeley by 75 * Digital Equipment Corporation and Ralph Campbell. 76 * 77 * Redistribution and use in source and binary forms, with or without 78 * modification, are permitted provided that the following conditions 79 * are met: 80 * 1. Redistributions of source code must retain the above copyright 81 * notice, this list of conditions and the following disclaimer. 82 * 2. Redistributions in binary form must reproduce the above copyright 83 * notice, this list of conditions and the following disclaimer in the 84 * documentation and/or other materials provided with the distribution. 85 * 3. All advertising materials mentioning features or use of this software 86 * must display the following acknowledgement: 87 * This product includes software developed by the University of 88 * California, Berkeley and its contributors. 89 * 4. Neither the name of the University nor the names of its contributors 90 * may be used to endorse or promote products derived from this software 91 * without specific prior written permission. 92 * 93 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 94 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 95 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 96 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 97 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 98 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 99 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 101 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 102 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 103 * SUCH DAMAGE. 104 * 105 * Copyright (C) 1989 Digital Equipment Corporation. 106 * Permission to use, copy, modify, and distribute this software and 107 * its documentation for any purpose and without fee is hereby granted, 108 * provided that the above copyright notice appears in all copies. 109 * Digital Equipment Corporation makes no representations about the 110 * suitability of this software for any purpose. It is provided "as is" 111 * without express or implied warranty. 112 * 113 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, 114 * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) 115 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, 116 * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) 117 * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, 118 * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) 119 * 120 * @(#)locore.s 8.5 (Berkeley) 1/4/94 121 */ 122#include "opt_cputype.h" 123#include "opt_ddb.h" 124#include "opt_kgdb.h" 125 126#include <sys/cdefs.h> 127 128#include <mips/asm.h> 129#include <mips/cpuregs.h> 130#if defined(MIPS3) && !defined(MIPS3_5900) 131#include <mips/cache_r4k.h> 132#endif 133 134#include <machine/param.h> 135#include <machine/endian.h> 136 137#include "assym.h" 138 139/* 140 * XXX MIPS3_5900 is still "special" for much of this code. 141 * XXX MIPS3_4100 is still "special" in tlb update code 142 */ 143 144#if MIPS1 145#error This file can not be compiled with MIPS1 defined 146#endif 147 148#if MIPS3 + MIPS32 + MIPS64 != 1 149# error Only one of MIPS{3,32,64} can be defined 150#endif 151 152/* 153 * Use 64bit cp0 instructions? 154 */ 155#if defined(MIPS3) 156#if defined(MIPS3_5900) /* the 5900 has mips32-like mmu registers */ 157#undef USE_64BIT_FUNCTIONS 158#else 159#define USE_64BIT_FUNCTIONS 160#endif 161#endif 162 163#if defined(MIPS32) 164#undef USE_64BIT_FUNCTIONS 165#endif 166 167#if defined(MIPS64) 168#define USE_64BIT_FUNCTIONS 169#endif 170 171#if defined(USE_64BIT_FUNCTIONS) 172#define _SLL dsll 173#define _SRL dsrl 174#define WIRED_SHIFT 34 175#else 176#define _SLL sll 177#define _SRL srl 178#define WIRED_SHIFT 2 179#endif 180 181/* 182 * Use correct-sized m?c0/dm?c0 opcodes. 183 */ 184#if defined(USE_64BIT_FUNCTIONS) 185#define _MFC0 dmfc0 186#define _MTC0 dmtc0 187#else 188#define _MFC0 mfc0 189#define _MTC0 mtc0 190#endif 191 192 193/* 194 * Set ISA level for the assembler. 195 */ 196#if defined(MIPS3) 197 .set mips3 198#endif 199 200#if defined(MIPS32) 201 .set mips32 202#endif 203 204#if defined(MIPS64) 205 .set mips64 206#endif 207 208/* 209 * Set up hazard/interlock dependancies. 210 */ 211#if !defined(MIPS3_5900) 212#undef COP0_SYNC 213#define COP0_SYNC /* nothing */ 214#endif 215 216/* 217 * CPP function renaming macros. 218 */ 219#if defined(LOSING_WITH_CPP) 220 221#if defined(MIPS3) 222#define MIPSX_PREFIX mips3 223#endif 224 225#if defined(MIPS32) 226#define MIPSX_PREFIX mips32 227#endif 228 229#if defined(MIPS64) 230#define MIPSX_PREFIX mips64 231#endif 232 233#ifdef __STDC__ 234#define MIPSX(name) MIPSX_PREFIX ## _ ## name 235#else 236#define MIPSX(name) MIPSX_PREFIX/**/_/**/name 237#endif 238 239#else /* LOSING_WITH_CPP */ 240 241#if defined(MIPS3) 242#define MIPSX(name) mips3_/**/name 243#endif 244 245#if defined(MIPS3_5900) 246#undef MIPSX 247#define MIPSX(name) mips5900_/**/name 248#endif 249 250#if defined(MIPS32) 251#define MIPSX(name) mips32_/**/name 252#endif 253 254#if defined(MIPS64) 255#define MIPSX(name) mips64_/**/name 256#endif 257 258#endif /* LOSING_WITH_CPP */ 259 260/* 261 * XXX We need a cleaner way of handling the instruction hazards of 262 * the various processors. Here are the relevant rules for the QED 52XX: 263 * tlbw[ri] -- two integer ops beforehand 264 * tlbr -- two integer ops beforehand 265 * tlbp -- two integer ops beforehand 266 * mtc0 [PageMask,EntryHi,Cp0] -- two integer ops afterwards 267 * changing JTLB -- two integer ops afterwards 268 * mtc0 [EPC,ErrorEPC,Status] -- two int ops afterwards before eret 269 * config.k0 -- five int ops before kseg0, ckseg0 memref 270 * 271 * For the IDT R4000, some hazards are: 272 * mtc0/mfc0 one integer op before and after 273 * tlbp -- one integer op afterwards 274 * Obvious solution is to take least common denominator. 275 * 276 * For the Toshiba R5900, TX79: 277 * mtc0 following sync.p 278 * tlbw[ri], tlbp following sync.p or eret 279 * for those CPU, define COP0_SYNC as sync.p 280 */ 281 282 283/* 284 *============================================================================ 285 * 286 * MIPS III ISA support, part 1: locore exception vectors. 287 * The following code is copied to the vector locations to which 288 * the CPU jumps in response to an exception or a TLB miss. 289 * 290 *============================================================================ 291 */ 292 .set noreorder 293 294/* 295 * TLB handling data. 'segbase' points to the base of the segment 296 * table. this is read and written by C code in mips_machdep.c. 297 * 298 * XXX: use linear mapped PTs at fixed VA in kseg2 in the future? 299 */ 300 .text 301 302 303/* 304 *---------------------------------------------------------------------------- 305 * 306 * mips3_TLBMiss -- 307 * 308 * Vector code for the TLB-miss exception vector 0x80000000 309 * on an r4000. 310 * 311 * This code is copied to the TLB exception vector address to 312 * handle TLB translation misses. 313 * NOTE: This code should be relocatable and max 32 instructions!!! 314 * 315 * Don't check for invalid pte's here. We load them as well and 316 * let the processor trap to load the correct value after service. 317 *---------------------------------------------------------------------------- 318 */ 319VECTOR(MIPSX(TLBMiss), unknown) 320 .set noat 321 mfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address 322 lui k1, %hi(segbase) #01: k1=hi of segbase 323 bltz k0, 4f #02: k0<0 -> 4f (kernel fault) 324 srl k0, 20 #03: k0=seg offset (almost) 325 lw k1, %lo(segbase)(k1) #04: k1=segment tab base 326 andi k0, k0, 0xffc #05: k0=seg offset (mask 0x3) 327 addu k1, k0, k1 #06: k1=seg entry address 328 lw k1, 0(k1) #07: k1=seg entry 329 mfc0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) 330 beq k1, zero, 5f #09: ==0 -- no page table 331 srl k0, 10 #0a: k0=VPN (aka va>>10) 332 andi k0, k0, 0xff8 #0b: k0=page tab offset 333 addu k1, k1, k0 #0c: k1=pte address 334 lw k0, 0(k1) #0d: k0=lo0 pte 335 lw k1, 4(k1) #0e: k1=lo1 pte 336 sll k0, 2 #0f: chop top 2 bits (part 1a) 337 srl k0, 2 #10: chop top 2 bits (part 1b) 338#ifdef MIPS3_5900 339 mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded 340 sync.p #12: R5900 cop0 hazard 341 sll k1, 2 #13: chop top 2 bits (part 2a) 342 srl k1, 2 #14: chop top 2 bits (part 2b) 343 mtc0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded 344 sync.p #16: R5900 cop0 hazard 345#else /* MIPS3_5900 */ 346 mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded 347 sll k1, 2 #12: chop top 2 bits (part 2a) 348 srl k1, 2 #13: chop top 2 bits (part 2b) 349 mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded 350 nop #15: standard nop 351 nop #16: extra nop for QED5230 352#endif /* MIPS3_5900 */ 353 tlbwr #17: write to tlb 354 nop #18: standard nop 355 nop #19: needed by R4000/4400 356 nop #1a: needed by R4000/4400 357 eret #1b: return from exception 3584: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception 359 nop #1d: branch delay slot 3605: j slowfault #1e: no page table present 361 nop #1f: branch delay slot 362 .set at 363VECTOR_END(MIPSX(TLBMiss)) 364 365#if defined(USE_64BIT_FUNCTIONS) 366/* 367 * mips3_XTLBMiss routine 368 * 369 * Vector code for the XTLB-miss exception vector 0x80000080 on an r4000. 370 * 371 * This code is copied to the XTLB exception vector address to 372 * handle TLB translation misses while in 64-bit mode. 373 * NOTE: This code should be relocatable and max 32 instructions!!! 374 * 375 * Note that we do not support the full size of the PTEs, relying 376 * on appropriate truncation/sign extension. 377 * 378 * Don't check for invalid pte's here. We load them as well and 379 * let the processor trap to load the correct value after service. 380 */ 381VECTOR(MIPSX(XTLBMiss), unknown) 382 .set noat 383 dmfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address 384 lui k1, %hi(segbase) #01: k1=hi of segbase 385 bltz k0, 4f #02: k0<0 -> 4f (kernel fault) 386 srl k0, 20 #03: k0=seg offset (almost) 387 lw k1, %lo(segbase)(k1) #04: k1=segment tab base 388 andi k0, k0, 0xffc #05: k0=seg offset (mask 0x3) 389 addu k1, k0, k1 #06: k1=seg entry address 390 lw k1, 0(k1) #07: k1=seg entry 391 dmfc0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) 392 beq k1, zero, 5f #09: ==0 -- no page table 393 srl k0, 10 #0a: k0=VPN (aka va>>10) 394 andi k0, k0, 0xff8 #0b: k0=page tab offset 395 addu k1, k1, k0 #0c: k1=pte address 396 lw k0, 0(k1) #0d: k0=lo0 pte 397 lw k1, 4(k1) #0e: k1=lo1 pte 398 sll k0, 2 #0f: chop top 2 bits (part 1a) 399 srl k0, 2 #10: chop top 2 bits (part 1b) 400 mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded 401 sll k1, 2 #12: chop top 2 bits (part 2a) 402 srl k1, 2 #13: chop top 2 bits (part 2b) 403 mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded 404 nop #15: standard nop 405 nop #16: extra nop for QED5230 406 tlbwr #17: write to tlb 407 nop #18: standard nop 408 nop #19: needed by R4000/4400 409 nop #1a: needed by R4000/4400 410 eret #1b: return from exception 4114: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception 412 nop #1d: branch delay slot 4135: j slowfault #1e: no page table present 414 nop #1f: branch delay slot 415 .set at 416VECTOR_END(MIPSX(XTLBMiss)) 417#endif /* USE_64BIT_FUNCTIONS */ 418 419/* 420 * Vector to real handler in KSEG1. 421 */ 422VECTOR(MIPSX(cache), unknown) 423 la k0, _C_LABEL(MIPSX(cacheException)) 424 li k1, MIPS_PHYS_MASK 425 and k0, k1 426 li k1, MIPS_KSEG1_START 427 or k0, k1 428 j k0 429 nop 430VECTOR_END(MIPSX(cache)) 431 432/* 433 * Handle MIPS32/MIPS64 style interrupt exception vector. 434 */ 435VECTOR(MIPSX(intr), unknown) 436 la k0, MIPSX(KernIntr) 437 j k0 438 nop 439VECTOR_END(MIPSX(intr)) 440 441/* 442 *---------------------------------------------------------------------------- 443 * 444 * mipsN_exception -- 445 * 446 * Vector code for the general exception vector 0x80000180 447 * on an r4000 or r4400. 448 * 449 * This code is copied to the general exception vector address to 450 * handle most exceptions. 451 * NOTE: This code should be relocatable and max 32 instructions!!! 452 *---------------------------------------------------------------------------- 453 */ 454VECTOR(MIPSX(exception), unknown) 455/* 456 * Find out what mode we came from and jump to the proper handler. 457 */ 458 .set noat 459 mfc0 k0, MIPS_COP_0_STATUS #00: get the status register 460 mfc0 k1, MIPS_COP_0_CAUSE #01: get the cause register 461 and k0, k0, MIPS3_SR_KSU_USER #02: test for user mode 462 # sneaky but the bits are 463 # with us........ 464 sll k0, k0, 3 #03: shift user bit for cause index 465 and k1, k1, MIPS3_CR_EXC_CODE #04: mask out the cause bits. 466 or k1, k1, k0 #05: change index to user table 4671: 468 la k0, MIPSX(excpt_sw) #06: get base of the jump table 469 addu k0, k0, k1 #07: get the address of the 470 # function entry. Note that 471 # the cause is already 472 # shifted left by 2 bits so 473 # we dont have to shift. 474 lw k0, 0(k0) #08: get the function address 475 #nop # -slip- 476 477 j k0 #09: jump to the function 478 nop #0a: branch delay slot 479 .set at 480VECTOR_END(MIPSX(exception)) 481 482/*---------------------------------------------------------------------------- 483 * 484 * slowfault -- 485 * 486 * Alternate entry point into the mips3_UserGenException or 487 * or mips3_user_Kern_exception, when the ULTB miss handler couldn't 488 * find a TLB entry. 489 * 490 * Find out what mode we came from and call the appropriate handler. 491 * 492 *---------------------------------------------------------------------------- 493 */ 494 495/* 496 * We couldn't find a TLB entry. 497 * Find out what mode we came from and call the appropriate handler. 498 */ 499slowfault: 500 .set noat 501 mfc0 k0, MIPS_COP_0_STATUS 502 nop 503 and k0, k0, MIPS3_SR_KSU_USER 504 bne k0, zero, _C_LABEL(MIPSX(UserGenException)) 505 nop 506 .set at 507/* 508 * Fall though ... 509 */ 510 511/* 512 * mips3_KernGenException 513 * 514 * Handle an exception from kernel mode. 515 * Build trapframe on stack to hold interrupted kernel context, then 516 * call trap() to process the condition. 517 * 518 * trapframe is pointed to by the 5th arg 519 * and a dummy sixth argument is used to avoid alignment problems 520 * { 521 * register_t cf_args[4 + 1]; 522 * register_t cf_pad; (for 8 word alignment) 523 * register_t cf_sp; 524 * register_t cf_ra; 525 * mips_reg_t kf_regs[17]; - trapframe begins here 526 * mips_reg_t kf_sr; - 527 * mips_reg_t kf_mullo; - 528 * mips_reg_t kf_mulhi; - 529 * mips_reg_t kf_epc; - may be changed by trap() call 530 * }; 531 */ 532NESTED_NOPROFILE(MIPSX(KernGenException), KERNFRAME_SIZ, ra) 533 .set noat 534 .mask 0x80000000, -4 535#if defined(DDB) || defined(KGDB) 536 la k0, _C_LABEL(kdbaux) 537 REG_S s0, SF_REG_S0(k0) 538 REG_S s1, SF_REG_S1(k0) 539 REG_S s2, SF_REG_S2(k0) 540 REG_S s3, SF_REG_S3(k0) 541 REG_S s4, SF_REG_S4(k0) 542 REG_S s5, SF_REG_S5(k0) 543 REG_S s6, SF_REG_S6(k0) 544 REG_S s7, SF_REG_S7(k0) 545 REG_S sp, SF_REG_SP(k0) 546 REG_S s8, SF_REG_S8(k0) 547 REG_S gp, SF_REG_RA(k0) 548#endif 549/* 550 * Save the relevant kernel registers onto the stack. 551 * We don't need to save s0 - s8, sp and gp because 552 * the compiler does it for us. 553 */ 554 subu sp, sp, KERNFRAME_SIZ 555 REG_S AT, TF_BASE+TF_REG_AST(sp) 556 REG_S v0, TF_BASE+TF_REG_V0(sp) 557 REG_S v1, TF_BASE+TF_REG_V1(sp) 558 mflo v0 559 mfhi v1 560 REG_S a0, TF_BASE+TF_REG_A0(sp) 561 REG_S a1, TF_BASE+TF_REG_A1(sp) 562 REG_S a2, TF_BASE+TF_REG_A2(sp) 563 REG_S a3, TF_BASE+TF_REG_A3(sp) 564 mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS 565 REG_S t0, TF_BASE+TF_REG_T0(sp) 566 REG_S t1, TF_BASE+TF_REG_T1(sp) 567 REG_S t2, TF_BASE+TF_REG_T2(sp) 568 REG_S t3, TF_BASE+TF_REG_T3(sp) 569 mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE 570 REG_S t4, TF_BASE+TF_REG_T4(sp) 571 REG_S t5, TF_BASE+TF_REG_T5(sp) 572 REG_S t6, TF_BASE+TF_REG_T6(sp) 573 REG_S t7, TF_BASE+TF_REG_T7(sp) 574 mfc0 a2, MIPS_COP_0_BAD_VADDR # 3rd arg is fault address 575 REG_S t8, TF_BASE+TF_REG_T8(sp) 576 REG_S t9, TF_BASE+TF_REG_T9(sp) 577 REG_S ra, TF_BASE+TF_REG_RA(sp) 578 REG_S a0, TF_BASE+TF_REG_SR(sp) 579 mfc0 a3, MIPS_COP_0_EXC_PC # 4th arg is exception PC 580 REG_S v0, TF_BASE+TF_REG_MULLO(sp) 581 REG_S v1, TF_BASE+TF_REG_MULHI(sp) 582 REG_S a3, TF_BASE+TF_REG_EPC(sp) 583 addu v0, sp, TF_BASE 584 sw v0, KERNFRAME_ARG5(sp) # 5th arg is p. to trapframe 585#ifdef IPL_ICU_MASK 586 .set at 587 lw v0, _C_LABEL(md_imask) 588 sw v0, TF_BASE+TF_PPL(sp) 589 nop 590 .set noat 591#endif 592/* 593 * Call the trap handler. 594 */ 595#if defined(DDB) || defined(DEBUG) || defined(KGDB) 596 addu v0, sp, KERNFRAME_SIZ 597 sw v0, KERNFRAME_SP(sp) 598#endif 599 mtc0 zero, MIPS_COP_0_STATUS # Set kernel no error level 600 COP0_SYNC 601 nop 602 nop 603 nop 604 jal _C_LABEL(trap) # 605 sw a3, KERNFRAME_RA(sp) # for debugging 606 607/* 608 * Restore registers and return from the exception. 609 */ 610 mtc0 zero, MIPS_COP_0_STATUS # Make sure int disabled 611 COP0_SYNC 612 nop # 3 nop delay 613 nop 614 nop 615#ifdef IPL_ICU_MASK 616 .set at 617 lw a0, TF_BASE+TF_PPL(sp) 618 sw a0, _C_LABEL(md_imask) 619 jal _C_LABEL(md_imask_update) 620 nop 621 .set noat 622#endif 623 REG_L a0, TF_BASE+TF_REG_SR(sp) # ??? why differs ??? 624 REG_L t0, TF_BASE+TF_REG_MULLO(sp) 625 REG_L t1, TF_BASE+TF_REG_MULHI(sp) 626 REG_L k0, TF_BASE+TF_REG_EPC(sp) # might be changed inside trap 627 mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs 628 COP0_SYNC 629 mtlo t0 630 mthi t1 631 _MTC0 k0, MIPS_COP_0_EXC_PC # set return address 632 COP0_SYNC 633 REG_L AT, TF_BASE+TF_REG_AST(sp) 634 REG_L v0, TF_BASE+TF_REG_V0(sp) 635 REG_L v1, TF_BASE+TF_REG_V1(sp) 636 REG_L a0, TF_BASE+TF_REG_A0(sp) 637 REG_L a1, TF_BASE+TF_REG_A1(sp) 638 REG_L a2, TF_BASE+TF_REG_A2(sp) 639 REG_L a3, TF_BASE+TF_REG_A3(sp) 640 REG_L t0, TF_BASE+TF_REG_T0(sp) 641 REG_L t1, TF_BASE+TF_REG_T1(sp) 642 REG_L t2, TF_BASE+TF_REG_T2(sp) 643 REG_L t3, TF_BASE+TF_REG_T3(sp) 644 REG_L t4, TF_BASE+TF_REG_T4(sp) 645 REG_L t5, TF_BASE+TF_REG_T5(sp) 646 REG_L t6, TF_BASE+TF_REG_T6(sp) 647 REG_L t7, TF_BASE+TF_REG_T7(sp) 648 REG_L t8, TF_BASE+TF_REG_T8(sp) 649 REG_L t9, TF_BASE+TF_REG_T9(sp) 650 REG_L ra, TF_BASE+TF_REG_RA(sp) 651 addu sp, sp, KERNFRAME_SIZ 652#ifdef DDBnotyet 653 la k0, _C_LABEL(kdbaux) 654 REG_L s0, SF_REG_S0(k0) 655 REG_L s1, SF_REG_S1(k0) 656 REG_L s2, SF_REG_S2(k0) 657 REG_L s3, SF_REG_S3(k0) 658 REG_L s4, SF_REG_S4(k0) 659 REG_L s5, SF_REG_S5(k0) 660 REG_L s6, SF_REG_S6(k0) 661 REG_L s7, SF_REG_S7(k0) 662 REG_L sp, SF_REG_SP(k0) 663 REG_L s8, SF_REG_S8(k0) 664 REG_L gp, SF_REG_RA(k0) 665#endif 666 eret # return to interrupted point 667 .set at 668END(MIPSX(KernGenException)) 669 670/* 671 * mipsN_UserGenException 672 * 673 * Handle an exception from user mode. 674 * Save user context atop the kernel stack, then call trap() to process 675 * the condition. The context can be manipulated alternatively via 676 * curproc->p_md.md_regs. 677 */ 678NESTED_NOPROFILE(MIPSX(UserGenException), CALLFRAME_SIZ, ra) 679 .set noat 680 .mask 0x80000000, -4 681/* 682 * Save all of the registers except for the kernel temporaries in u_pcb. 683 */ 684 lw k1, _C_LABEL(curpcb) 685 #nop # -slip- 686 addu k1, k1, USPACE - FRAME_SIZ 687 REG_S AT, FRAME_AST(k1) 688 REG_S v0, FRAME_V0(k1) 689 REG_S v1, FRAME_V1(k1) 690 mflo v0 691 REG_S a0, FRAME_A0(k1) 692 REG_S a1, FRAME_A1(k1) 693 REG_S a2, FRAME_A2(k1) 694 REG_S a3, FRAME_A3(k1) 695 mfhi v1 696 REG_S t0, FRAME_T0(k1) 697 REG_S t1, FRAME_T1(k1) 698 REG_S t2, FRAME_T2(k1) 699 REG_S t3, FRAME_T3(k1) 700 mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS 701 REG_S t4, FRAME_T4(k1) 702 REG_S t5, FRAME_T5(k1) 703 REG_S t6, FRAME_T6(k1) 704 REG_S t7, FRAME_T7(k1) 705 mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE 706 REG_S s0, FRAME_S0(k1) 707 REG_S s1, FRAME_S1(k1) 708 REG_S s2, FRAME_S2(k1) 709 REG_S s3, FRAME_S3(k1) 710 _MFC0 a2, MIPS_COP_0_BAD_VADDR # 3rd arg is fault address 711 REG_S s4, FRAME_S4(k1) 712 REG_S s5, FRAME_S5(k1) 713 REG_S s6, FRAME_S6(k1) 714 REG_S s7, FRAME_S7(k1) 715 _MFC0 a3, MIPS_COP_0_EXC_PC # 4th arg is exception PC 716 REG_S t8, FRAME_T8(k1) 717 REG_S t9, FRAME_T9(k1) 718 REG_S gp, FRAME_GP(k1) 719 REG_S sp, FRAME_SP(k1) 720 REG_S s8, FRAME_S8(k1) 721 REG_S ra, FRAME_RA(k1) 722 REG_S a0, FRAME_SR(k1) 723 REG_S v0, FRAME_MULLO(k1) 724 REG_S v1, FRAME_MULHI(k1) 725 REG_S a3, FRAME_EPC(k1) 726#ifdef IPL_ICU_MASK 727 .set at 728 lw t0, _C_LABEL(md_imask) 729 sw t0, FRAME_PPL(k1) 730 .set noat 731#endif 732 addu sp, k1, -CALLFRAME_SIZ # switch to kernel SP 733#ifdef __GP_SUPPORT__ 734 la gp, _C_LABEL(_gp) # switch to kernel GP 735#endif 736/* 737 * Turn off fpu and enter kernel mode 738 */ 739 .set at 740 and t0, a0, ~(MIPS_SR_COP_1_BIT | MIPS_SR_EXL | MIPS_SR_KSU_MASK | MIPS_SR_INT_IE) 741 .set noat 742/* 743 * Call the trap handler. 744 */ 745 mtc0 t0, MIPS_COP_0_STATUS 746 COP0_SYNC 747 jal _C_LABEL(trap) 748 sw a3, CALLFRAME_SIZ-4(sp) # for debugging 749/* 750 * Check pending asynchronous traps. 751 */ 752 lw t0, _C_LABEL(curproc) 753 lw t0, P_MD_ASTPENDING(t0) 754 beq t0, zero, 1f 755 nop 756/* 757 * We have pending asynchronous traps; all the state is already saved. 758 */ 759 jal _C_LABEL(ast) 760 lw a0, CALLFRAME_SIZ + FRAME_EPC(sp) 7611: 762/* 763 * Restore user registers and return. 764 * First disable interrupts and set exception level. 765 */ 766 mtc0 zero, MIPS_COP_0_STATUS # disable interrupt 767 COP0_SYNC 768 nop # 3 clock delay before 769 nop # exceptions blocked 770 nop # for R4X 771 li v0, MIPS_SR_EXL 772 mtc0 v0, MIPS_COP_0_STATUS # set exception level 773 COP0_SYNC 774 nop # 3 nop delay 775 nop 776 nop 777 addu a1, sp, CALLFRAME_SIZ 778#ifdef IPL_ICU_MASK 779 .set at 780 lw t0, FRAME_PPL(a1) 781 sw t0, _C_LABEL(md_imask) 782 jal _C_LABEL(md_imask_update) 783 nop 784 addu a1, sp, CALLFRAME_SIZ 785 .set noat 786#endif 787 # REG_L a0, FRAME_SR(a1) 788 REG_L t0, FRAME_MULLO(a1) 789 REG_L t1, FRAME_MULHI(a1) 790 REG_L v0, FRAME_EPC(a1) 791 # mtc0 a0, MIPS_COP_0_STATUS # still exception level 792 mtlo t0 793 mthi t1 794 _MTC0 v0, MIPS_COP_0_EXC_PC # set return address 795 COP0_SYNC 796 move k1, a1 797 REG_L AT, FRAME_AST(k1) 798 REG_L v0, FRAME_V0(k1) 799 REG_L v1, FRAME_V1(k1) 800 REG_L a0, FRAME_A0(k1) 801 REG_L a1, FRAME_A1(k1) 802 REG_L a2, FRAME_A2(k1) 803 REG_L a3, FRAME_A3(k1) 804 REG_L t0, FRAME_T0(k1) 805 REG_L t1, FRAME_T1(k1) 806 REG_L t2, FRAME_T2(k1) 807 REG_L t3, FRAME_T3(k1) 808 REG_L t4, FRAME_T4(k1) 809 REG_L t5, FRAME_T5(k1) 810 REG_L t6, FRAME_T6(k1) 811 REG_L t7, FRAME_T7(k1) 812 REG_L s0, FRAME_S0(k1) 813 REG_L s1, FRAME_S1(k1) 814 REG_L s2, FRAME_S2(k1) 815 REG_L s3, FRAME_S3(k1) 816 REG_L s4, FRAME_S4(k1) 817 REG_L s5, FRAME_S5(k1) 818 REG_L s6, FRAME_S6(k1) 819 REG_L s7, FRAME_S7(k1) 820 REG_L t8, FRAME_T8(k1) 821 REG_L t9, FRAME_T9(k1) 822 REG_L k0, FRAME_SR(k1) 823 DYNAMIC_STATUS_MASK_TOUSER(k0,ra) # machine dependent masking 824 REG_L gp, FRAME_GP(k1) 825 REG_L sp, FRAME_SP(k1) 826 REG_L s8, FRAME_S8(k1) 827 REG_L ra, FRAME_RA(k1) 828 mtc0 k0, MIPS_COP_0_STATUS # restore status 829 COP0_SYNC 830 nop 831 nop 832 eret # return to interrupted point 833 .set at 834END(MIPSX(UserGenException)) 835 836/* 837 * mipsN_SystemCall 838 * 839 * Save user context in u_pcb, then call syscall() to process a system call. 840 * The context can be manipulated alternatively via curproc->p_md.md_regs; 841 */ 842NESTED_NOPROFILE(MIPSX(SystemCall), CALLFRAME_SIZ, ra) 843 .set noat 844 .mask 0x80000000, -4 845 lw k1, _C_LABEL(curpcb) 846 #nop # -slip- 847 addu k1, k1, USPACE - FRAME_SIZ 848 #REG_S AT, FRAME_AST(k1) 849 REG_S v0, FRAME_V0(k1) # syscall # 850 REG_S v1, FRAME_V1(k1) # used by syscall() 851 mflo v0 852 REG_S a0, FRAME_A0(k1) 853 REG_S a1, FRAME_A1(k1) 854 REG_S a2, FRAME_A2(k1) 855 REG_S a3, FRAME_A3(k1) 856 lw a0, _C_LABEL(curproc) # 1st arg is curproc 857 mfhi v1 858 #REG_S t0, FRAME_T0(k1) # no need to save temp regs 859 #REG_S t1, FRAME_T1(k1) 860 #REG_S t2, FRAME_T2(k1) 861 #REG_S t3, FRAME_T3(k1) 862 mfc0 a1, MIPS_COP_0_STATUS # 2nd arg is STATUS 863 #REG_S t4, FRAME_T4(k1) 864 #REG_S t5, FRAME_T5(k1) 865 #REG_S t6, FRAME_T6(k1) 866 #REG_S t7, FRAME_T7(k1) 867 mfc0 a2, MIPS_COP_0_CAUSE # 3rd arg is CAUSE 868 REG_S s0, FRAME_S0(k1) 869 REG_S s1, FRAME_S1(k1) 870 REG_S s2, FRAME_S2(k1) 871 REG_S s3, FRAME_S3(k1) 872 mfc0 a3, MIPS_COP_0_EXC_PC # 4th arg is PC 873 REG_S s4, FRAME_S4(k1) 874 REG_S s5, FRAME_S5(k1) 875 REG_S s6, FRAME_S6(k1) 876 REG_S s7, FRAME_S7(k1) 877 #REG_S t8, FRAME_T8(k1) 878 #REG_S t9, FRAME_T9(k1) 879 REG_S gp, FRAME_GP(k1) 880 REG_S sp, FRAME_SP(k1) 881 REG_S s8, FRAME_S8(k1) 882 REG_S ra, FRAME_RA(k1) 883 REG_S a1, FRAME_SR(k1) 884 REG_S v0, FRAME_MULLO(k1) 885 REG_S v1, FRAME_MULHI(k1) 886 REG_S a3, FRAME_EPC(k1) 887#ifdef IPL_ICU_MASK 888 .set at 889 lw t0, _C_LABEL(md_imask) 890 sw t0, FRAME_PPL(k1) 891 .set noat 892#endif 893 addu sp, k1, -CALLFRAME_SIZ 894#ifdef __GP_SUPPORT__ 895 la gp, _C_LABEL(_gp) # switch to kernel GP 896#endif 897/* 898 * Turn off fpu and enter kernel mode 899 */ 900 .set at 901 lw t1, P_MD_SYSCALL(a0) # t1 = syscall 902 and t0, a1, ~(MIPS_SR_COP_1_BIT | MIPS_SR_EXL | MIPS_SR_KSU_MASK) 903 .set noat 904#if defined(DDB) || defined(DEBUG) || defined(KGDB) 905 move ra, a3 906 sw ra, CALLFRAME_RA(sp) 907#endif 908/* 909 * Call the system call handler. 910 */ 911 mtc0 t0, MIPS_COP_0_STATUS # re-enable interrupts 912 COP0_SYNC 913 jal t1 914 nop 915/* 916 * Check pending asynchronous traps. 917 */ 918 lw t0, _C_LABEL(curproc) 919 lw t0, P_MD_ASTPENDING(t0) 920 beq t0, zero, 1f 921 nop 922/* 923 * We have pending asynchronous traps; all the state is already saved. 924 */ 925 jal _C_LABEL(ast) 926 lw a0, CALLFRAME_SIZ + FRAME_EPC(sp) 9271: 928/* 929 * Restore user registers and return. 930 * First disable interrupts and set exception level. 931 */ 932 mtc0 zero, MIPS_COP_0_STATUS # disable int 933 COP0_SYNC 934 nop # 3 op delay 935 nop 936 nop 937 938 li v0, MIPS_SR_EXL 939 mtc0 v0, MIPS_COP_0_STATUS # set exception level 940 COP0_SYNC 941 nop # 3 op delay 942 nop 943 nop 944/* 945 * Restore user registers and return. 946 */ 947 addu a1, sp, CALLFRAME_SIZ 948#ifdef IPL_ICU_MASK 949 .set at 950 lw t0, FRAME_PPL(a1) 951 sw t0, _C_LABEL(md_imask) 952 jal _C_LABEL(md_imask_update) 953 nop 954 addu a1, sp, CALLFRAME_SIZ 955 .set noat 956#endif 957 # REG_L a0, FRAME_SR(a1) 958 REG_L t0, FRAME_MULLO(a1) 959 REG_L t1, FRAME_MULHI(a1) 960 REG_L v0, FRAME_EPC(a1) # might be changed in syscall 961 # mtc0 a0, MIPS_COP_0_STATUS # this should disable interrupts 962 mtlo t0 963 mthi t1 964 _MTC0 v0, MIPS_COP_0_EXC_PC # set return address 965 COP0_SYNC 966 move k1, a1 967 REG_L AT, FRAME_AST(k1) 968 REG_L v0, FRAME_V0(k1) 969 REG_L v1, FRAME_V1(k1) 970 REG_L a0, FRAME_A0(k1) 971 REG_L a1, FRAME_A1(k1) 972 REG_L a2, FRAME_A2(k1) 973 REG_L a3, FRAME_A3(k1) 974 REG_L t0, FRAME_T0(k1) 975 REG_L t1, FRAME_T1(k1) 976 REG_L t2, FRAME_T2(k1) 977 REG_L t3, FRAME_T3(k1) 978 REG_L t4, FRAME_T4(k1) 979 REG_L t5, FRAME_T5(k1) 980 REG_L t6, FRAME_T6(k1) 981 REG_L t7, FRAME_T7(k1) 982 REG_L s0, FRAME_S0(k1) 983 REG_L s1, FRAME_S1(k1) 984 REG_L s2, FRAME_S2(k1) 985 REG_L s3, FRAME_S3(k1) 986 REG_L s4, FRAME_S4(k1) 987 REG_L s5, FRAME_S5(k1) 988 REG_L s6, FRAME_S6(k1) 989 REG_L s7, FRAME_S7(k1) 990 REG_L t8, FRAME_T8(k1) 991 REG_L t9, FRAME_T9(k1) 992 REG_L k0, FRAME_SR(k1) 993 DYNAMIC_STATUS_MASK_TOUSER(k0,ra) # machine dependent masking 994 REG_L gp, FRAME_GP(k1) 995 REG_L sp, FRAME_SP(k1) 996 REG_L s8, FRAME_S8(k1) 997 REG_L ra, FRAME_RA(k1) 998 mtc0 k0, MIPS_COP_0_STATUS 999 COP0_SYNC 1000 nop 1001 nop 1002 nop 1003 1004 eret # return to syscall point 1005 .set at 1006END(MIPSX(SystemCall)) 1007 1008/* 1009 * Panic on cache errors. A lot more could be done to recover 1010 * from some types of errors but it is tricky. 1011 */ 1012NESTED_NOPROFILE(MIPSX(cacheException), KERNFRAME_SIZ, ra) 1013 .set noat 1014 .mask 0x80000000, -4 1015#ifdef sbmips /* XXX! SB-1 needs a real cache error handler */ 1016 eret 1017 nop 1018#endif 1019 la k0, panic # return to panic 1020 la a0, 9f # panicstr 1021 _MFC0 a1, MIPS_COP_0_ERROR_PC 1022 mfc0 a2, MIPS_COP_0_ECC 1023 mfc0 a3, MIPS_COP_0_CACHE_ERR 1024 1025 _MTC0 k0, MIPS_COP_0_ERROR_PC # set return address 1026 COP0_SYNC 1027 1028 mfc0 k0, MIPS_COP_0_STATUS # restore status 1029 li k1, MIPS3_SR_DIAG_PE # ignore further errors 1030 or k0, k1 1031 mtc0 k0, MIPS_COP_0_STATUS # restore status 1032 COP0_SYNC 1033 nop 1034 nop 1035 nop 1036 1037 eret 1038 1039 MSG("cache error @ EPC 0x%x ErrCtl 0x%x CacheErr 0x%x"); 1040 .set at 1041END(MIPSX(cacheException)) 1042 1043/* 1044 * mipsX_KernIntr 1045 * 1046 * Handle an interrupt from kernel mode. 1047 * Build intrframe on stack to hold interrupted kernel context, then 1048 * call cpu_intr() to process it. 1049 * 1050 */ 1051NESTED_NOPROFILE(MIPSX(KernIntr), KERNFRAME_SIZ, ra) 1052 .set noat 1053 .mask 0x80000000, -4 1054 subu sp, sp, KERNFRAME_SIZ 1055/* 1056 * Save the relevant kernel registers onto the stack. 1057 * We don't need to save s0 - s8, sp and gp because 1058 * the compiler does it for us. 1059 */ 1060 REG_S AT, TF_BASE+TF_REG_AST(sp) 1061 REG_S v0, TF_BASE+TF_REG_V0(sp) 1062 REG_S v1, TF_BASE+TF_REG_V1(sp) 1063 mflo v0 1064 mfhi v1 1065 REG_S a0, TF_BASE+TF_REG_A0(sp) 1066 REG_S a1, TF_BASE+TF_REG_A1(sp) 1067 REG_S a2, TF_BASE+TF_REG_A2(sp) 1068 REG_S a3, TF_BASE+TF_REG_A3(sp) 1069 mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS 1070 REG_S t0, TF_BASE+TF_REG_T0(sp) 1071 REG_S t1, TF_BASE+TF_REG_T1(sp) 1072 REG_S t2, TF_BASE+TF_REG_T2(sp) 1073 REG_S t3, TF_BASE+TF_REG_T3(sp) 1074 mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE 1075 REG_S t4, TF_BASE+TF_REG_T4(sp) 1076 REG_S t5, TF_BASE+TF_REG_T5(sp) 1077 REG_S t6, TF_BASE+TF_REG_T6(sp) 1078 REG_S t7, TF_BASE+TF_REG_T7(sp) 1079 mfc0 a2, MIPS_COP_0_EXC_PC # 3rd arg is exception PC 1080 REG_S t8, TF_BASE+TF_REG_T8(sp) 1081 REG_S t9, TF_BASE+TF_REG_T9(sp) 1082 REG_S ra, TF_BASE+TF_REG_RA(sp) 1083 REG_S a0, TF_BASE+TF_REG_SR(sp) 1084 REG_S v0, TF_BASE+TF_REG_MULLO(sp) 1085 REG_S v1, TF_BASE+TF_REG_MULHI(sp) 1086 REG_S a2, TF_BASE+TF_REG_EPC(sp) 1087/* 1088 * Call the interrupt handler. 1089 */ 1090#if defined(DDB) || defined(DEBUG) || defined(KGDB) 1091 move ra, a2 1092 sw ra, KERNFRAME_RA(sp) # for debugging 1093#endif 1094#ifdef IPL_ICU_MASK 1095 .set at 1096 lw t0, _C_LABEL(md_imask) 1097 sw t0, TF_BASE+TF_PPL(sp) 1098 .set noat 1099#endif 1100 mtc0 zero, MIPS_COP_0_STATUS # Reset exl, trap possible. 1101 COP0_SYNC 1102 jal _C_LABEL(cpu_intr) 1103 and a3, a0, a1 # 4th is STATUS & CAUSE 1104/* 1105 * Restore registers and return from the interrupt. 1106 */ 1107 mtc0 zero, MIPS_COP_0_STATUS # Disable interrupt 1108 COP0_SYNC 1109 nop 1110 nop 1111 nop 1112#ifdef IPL_ICU_MASK 1113 .set at 1114 lw a0, TF_BASE+TF_PPL(sp) 1115 sw a0, _C_LABEL(md_imask) 1116 jal _C_LABEL(md_imask_update) 1117 nop 1118 .set noat 1119#endif 1120 REG_L a0, TF_BASE+TF_REG_SR(sp) # ??? why differs ??? 1121 DYNAMIC_STATUS_MASK(a0,t0) # machine dependent masking 1122 REG_L t0, TF_BASE+TF_REG_MULLO(sp) 1123 REG_L t1, TF_BASE+TF_REG_MULHI(sp) 1124 REG_L v0, TF_BASE+TF_REG_EPC(sp) 1125 mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs 1126 COP0_SYNC 1127 mtlo t0 1128 mthi t1 1129 _MTC0 v0, MIPS_COP_0_EXC_PC # set return address 1130 COP0_SYNC 1131 1132 REG_L AT, TF_BASE+TF_REG_AST(sp) 1133 REG_L v0, TF_BASE+TF_REG_V0(sp) 1134 REG_L v1, TF_BASE+TF_REG_V1(sp) 1135 REG_L a0, TF_BASE+TF_REG_A0(sp) 1136 REG_L a1, TF_BASE+TF_REG_A1(sp) 1137 REG_L a2, TF_BASE+TF_REG_A2(sp) 1138 REG_L a3, TF_BASE+TF_REG_A3(sp) 1139 REG_L t0, TF_BASE+TF_REG_T0(sp) 1140 REG_L t1, TF_BASE+TF_REG_T1(sp) 1141 REG_L t2, TF_BASE+TF_REG_T2(sp) 1142 REG_L t3, TF_BASE+TF_REG_T3(sp) 1143 REG_L t4, TF_BASE+TF_REG_T4(sp) 1144 REG_L t5, TF_BASE+TF_REG_T5(sp) 1145 REG_L t6, TF_BASE+TF_REG_T6(sp) 1146 REG_L t7, TF_BASE+TF_REG_T7(sp) 1147 REG_L t8, TF_BASE+TF_REG_T8(sp) 1148 REG_L t9, TF_BASE+TF_REG_T9(sp) 1149 REG_L ra, TF_BASE+TF_REG_RA(sp) 1150 addu sp, sp, KERNFRAME_SIZ # restore kernel SP 1151 eret # return to interrupted point 1152 .set at 1153END(MIPSX(KernIntr)) 1154 1155/*---------------------------------------------------------------------------- 1156 * XXX this comment block should be updated XXX 1157 * mipsN_UserIntr -- 1158 * 1159 * Handle an interrupt from user mode. 1160 * Note: we save minimal state in the u.u_pcb struct and use the standard 1161 * kernel stack since there has to be a u page if we came from user mode. 1162 * If there is a pending software interrupt, then save the remaining state 1163 * and call softintr(). This is all because if we call switch() inside 1164 * cpu_intr(), not all the user registers have been saved in u.u_pcb. 1165 * 1166 * Results: 1167 * None. 1168 * 1169 * Side effects: 1170 * None. 1171 * 1172 *---------------------------------------------------------------------------- 1173 */ 1174NESTED_NOPROFILE(MIPSX(UserIntr), CALLFRAME_SIZ, ra) 1175 .set noat 1176 .mask 0x80000000, -4 1177/* 1178 * Save the relevant user registers into the u_pcb. 1179 * We don't need to save s0 - s8 because the compiler does it for us. 1180 */ 1181 lw k1, _C_LABEL(curpcb) 1182 #nop # -slip- 1183 addu k1, k1, USPACE - FRAME_SIZ 1184 REG_S AT, FRAME_AST(k1) 1185 REG_S v0, FRAME_V0(k1) 1186 REG_S v1, FRAME_V1(k1) 1187 mflo v0 1188 REG_S a0, FRAME_A0(k1) 1189 REG_S a1, FRAME_A1(k1) 1190 REG_S a2, FRAME_A2(k1) 1191 REG_S a3, FRAME_A3(k1) 1192 mfhi v1 1193 REG_S t0, FRAME_T0(k1) 1194 REG_S t1, FRAME_T1(k1) 1195 REG_S t2, FRAME_T2(k1) 1196 REG_S t3, FRAME_T3(k1) 1197 mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS 1198 REG_S t4, FRAME_T4(k1) 1199 REG_S t5, FRAME_T5(k1) 1200 REG_S t6, FRAME_T6(k1) 1201 REG_S t7, FRAME_T7(k1) 1202 mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE 1203 REG_S t8, FRAME_T8(k1) 1204 REG_S t9, FRAME_T9(k1) 1205 REG_S gp, FRAME_GP(k1) 1206 REG_S sp, FRAME_SP(k1) 1207 mfc0 a2, MIPS_COP_0_EXC_PC # 3rd arg is PC 1208 REG_S ra, FRAME_RA(k1) 1209 REG_S a0, FRAME_SR(k1) 1210 REG_S v0, FRAME_MULLO(k1) 1211 REG_S v1, FRAME_MULHI(k1) 1212 REG_S a2, FRAME_EPC(k1) 1213#ifdef IPL_ICU_MASK 1214 .set at 1215 lw t0, _C_LABEL(md_imask) 1216 sw t0, FRAME_PPL(k1) 1217 .set noat 1218#endif 1219 addu sp, k1, -CALLFRAME_SIZ # switch to kernel SP 1220#ifdef __GP_SUPPORT__ 1221 la gp, _C_LABEL(_gp) # switch to kernel GP 1222#endif 1223/* 1224 * Turn off fpu and enter kernel mode 1225 */ 1226 .set at 1227 and t0, a0, ~(MIPS_SR_COP_1_BIT | MIPS_SR_EXL | MIPS_SR_INT_IE | MIPS_SR_KSU_MASK) 1228 .set noat 1229#if defined(DDB) || defined(DEBUG) || defined(KGDB) 1230 move ra, a2 1231 sw ra, CALLFRAME_RA(sp) 1232#endif 1233/* 1234 * Call the interrupt handler. 1235 */ 1236 mtc0 t0, MIPS_COP_0_STATUS 1237 COP0_SYNC 1238 jal _C_LABEL(cpu_intr) 1239 and a3, a0, a1 # 4th is STATUS & CAUSE 1240/* 1241 * Restore registers and return from the interrupt. 1242 */ 1243 nop 1244 mtc0 zero, MIPS_COP_0_STATUS 1245 COP0_SYNC 1246 nop # 3 nop hazard 1247 nop 1248 nop 1249 li v0, MIPS_SR_EXL 1250 mtc0 v0, MIPS_COP_0_STATUS # set exception level bit. 1251 COP0_SYNC 1252 nop # 3 nop hazard 1253 nop 1254 nop 1255 lw v0, _C_LABEL(curproc) 1256 addu a1, sp, CALLFRAME_SIZ 1257 # REG_L a0, FRAME_SR(a1) 1258 lw v0, P_MD_ASTPENDING(v0) # any pending ast? 1259 # mtc0 a0, MIPS_COP_0_STATUS # restore the SR, disable intrs 1260/* 1261 * Check pending asynchronous traps. 1262 */ 1263 beq v0, zero, 1f # if no, skip ast processing 1264 nop # -delay slot- 1265/* 1266 * We have pending asynchronous traps; save remaining user state in u_pcb. 1267 */ 1268 REG_S s0, FRAME_S0(a1) 1269 REG_S s1, FRAME_S1(a1) 1270 REG_S s2, FRAME_S2(a1) 1271 REG_S s3, FRAME_S3(a1) 1272 REG_S s4, FRAME_S4(a1) 1273 REG_S s5, FRAME_S5(a1) 1274 REG_S s6, FRAME_S6(a1) 1275 REG_S s7, FRAME_S7(a1) 1276 REG_S s8, FRAME_S8(a1) 1277 REG_L a0, FRAME_EPC(a1) # argument is interrupted PC 1278#ifdef IPL_ICU_MASK 1279 jal _C_LABEL(spllowersofthigh); 1280 nop 1281#else 1282 li t0, MIPS_HARD_INT_MASK | MIPS_SR_INT_IE 1283 DYNAMIC_STATUS_MASK(t0,t1) # machine dependent masking 1284 mtc0 t0, MIPS_COP_0_STATUS # enable interrupts (spl0) 1285 COP0_SYNC 1286#endif 1287 jal _C_LABEL(ast) 1288 nop 1289/* 1290 * Restore user registers and return. NOTE: interrupts are enabled. 1291 */ 1292 mtc0 zero, MIPS_COP_0_STATUS 1293 COP0_SYNC 1294 nop # 3 nop delay 1295 nop 1296 nop 1297 li v0, MIPS_SR_EXL 1298 mtc0 v0, MIPS_COP_0_STATUS # set exception level bit. 1299 COP0_SYNC 1300 nop # 3 nop delay 1301 nop 1302 nop 1303 1304 addu a1, sp, CALLFRAME_SIZ 1305 # REG_L a0, FRAME_SR(a1) 1306 REG_L s0, FRAME_S0(a1) 1307 REG_L s1, FRAME_S1(a1) 1308 REG_L s2, FRAME_S2(a1) 1309 REG_L s3, FRAME_S3(a1) 1310 REG_L s4, FRAME_S4(a1) 1311 REG_L s5, FRAME_S5(a1) 1312 REG_L s6, FRAME_S6(a1) 1313 REG_L s7, FRAME_S7(a1) 1314 REG_L s8, FRAME_S8(a1) 1315 # mtc0 a0, MIPS_COP_0_STATUS # this should disable interrupts 1316 13171: 1318 REG_L t0, FRAME_MULLO(a1) 1319 REG_L t1, FRAME_MULHI(a1) 1320 REG_L v0, FRAME_EPC(a1) 1321 mtlo t0 1322 mthi t1 1323 _MTC0 v0, MIPS_COP_0_EXC_PC # set return address 1324 COP0_SYNC 1325 nop # ??? how much delay ??? 1326 nop 1327 1328 move k1, a1 1329#ifdef IPL_ICU_MASK 1330 .set at 1331 lw t0, FRAME_PPL(k1) 1332 sw t0, _C_LABEL(md_imask) 1333 jal _C_LABEL(md_imask_update) 1334 nop 1335 .set noat 1336#endif 1337 REG_L AT, FRAME_AST(k1) 1338 REG_L v0, FRAME_V0(k1) 1339 REG_L v1, FRAME_V1(k1) 1340 REG_L a0, FRAME_A0(k1) 1341 REG_L a1, FRAME_A1(k1) 1342 REG_L a2, FRAME_A2(k1) 1343 REG_L a3, FRAME_A3(k1) 1344 REG_L t0, FRAME_T0(k1) 1345 REG_L t1, FRAME_T1(k1) 1346 REG_L t2, FRAME_T2(k1) 1347 REG_L t3, FRAME_T3(k1) 1348 REG_L t4, FRAME_T4(k1) 1349 REG_L t5, FRAME_T5(k1) 1350 REG_L t6, FRAME_T6(k1) 1351 REG_L t7, FRAME_T7(k1) 1352 REG_L t8, FRAME_T8(k1) 1353 REG_L t9, FRAME_T9(k1) 1354 REG_L k0, FRAME_SR(k1) 1355 DYNAMIC_STATUS_MASK_TOUSER(k0,ra) # machine dependent masking 1356 REG_L gp, FRAME_GP(k1) 1357 REG_L sp, FRAME_SP(k1) 1358 REG_L ra, FRAME_RA(k1) 1359 mtc0 k0, MIPS_COP_0_STATUS # restore the SR 1360 COP0_SYNC 1361 nop # required for QED 5230 1362 nop 1363 eret # return to interrupted point 1364 .set at 1365END(MIPSX(UserIntr)) 1366 1367 1368/*---------------------------------------------------------------------------- 1369 * 1370 * R4000 TLB exception handlers 1371 * 1372 *---------------------------------------------------------------------------- 1373 */ 1374 1375 1376/*---------------------------------------------------------------------------- 1377 * 1378 * mips3_TLBInvalidException -- 1379 * 1380 * Handle a TLB invalid exception from kernel mode in kernel space. 1381 * The BaddVAddr, Context, and EntryHi registers contain the failed 1382 * virtual address. 1383 * 1384 * The case of wired TLB entries is special. The wired TLB entries 1385 * are used to keep the u area TLB's valid. The PTE entries for these 1386 * do not have MIPS3_PG_G set; the kernel instead relies 1387 * on the switch_resume function to set these bits. 1388 * 1389 * To preserve this situation, we set PG_G bits on the "other" TLB entries 1390 * when they are wired. 1391 * 1392 * Results: 1393 * None. 1394 * 1395 * Side effects: 1396 * None. 1397 * 1398 *---------------------------------------------------------------------------- 1399 */ 1400LEAF_NOPROFILE(MIPSX(TLBInvalidException)) 1401 .set noat 1402 _MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address 1403 li k1, VM_MIN_KERNEL_ADDRESS # compute index 1404 bgez k0, _C_LABEL(MIPSX(KernGenException)) # full trap processing 1405 subu k0, k0, k1 1406 lw k1, _C_LABEL(Sysmapsize) # index within range? 1407 srl k0, k0, PGSHIFT 1408 sltu k1, k0, k1 1409 beq k1, zero, outofworld # No. Failing beyond. . . 1410 lw k1, _C_LABEL(Sysmap) 1411 1412 sll k0, k0, 2 # compute offset from index 1413 addu k1, k1, k0 1414 tlbp # Probe the invalid entry 1415 COP0_SYNC 1416 and k0, k0, 4 # check even/odd page 1417 nop # required for QED 5230 1418 bne k0, zero, KernTLBIOdd 1419 nop 1420 1421 mfc0 k0, MIPS_COP_0_TLB_INDEX 1422 nop 1423 bltz k0, outofworld # ASSERT(TLB entry exists) 1424 lw k0, 0(k1) # get PTE entry 1425 1426 _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit 1427 _SRL k0, k0, WIRED_SHIFT 1428 mtc0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry 1429 COP0_SYNC 1430 and k0, k0, MIPS3_PG_V # check for valid entry 1431 nop # required for QED5230 1432 beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid 1433 lw k0, 4(k1) # get odd PTE entry 1434 _SLL k0, k0, WIRED_SHIFT 1435 mfc0 k1, MIPS_COP_0_TLB_INDEX 1436 _SRL k0, k0, WIRED_SHIFT 1437 sltiu k1, k1, MIPS3_TLB_WIRED_UPAGES # Luckily this is MIPS3_PG_G 1438 or k1, k1, k0 1439 _MTC0 k0, MIPS_COP_0_TLB_LO1 # load PTE entry 1440 COP0_SYNC 1441 nop 1442 nop # required for QED5230 1443 tlbwi # write TLB 1444 COP0_SYNC 1445 nop 1446 nop 1447 nop 1448 nop 1449 nop 1450 eret 1451 1452KernTLBIOdd: 1453 mfc0 k0, MIPS_COP_0_TLB_INDEX 1454 nop 1455 bltz k0, outofworld # assert(TLB Entry exists) 1456 lw k0, 0(k1) # get PTE entry 1457 1458 _SLL k0, k0, WIRED_SHIFT # get rid of wired bit 1459 _SRL k0, k0, WIRED_SHIFT 1460 _MTC0 k0, MIPS_COP_0_TLB_LO1 # save PTE entry 1461 COP0_SYNC 1462 and k0, k0, MIPS3_PG_V # check for valid entry 1463 nop # required for QED5230 1464 beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid 1465 lw k0, -4(k1) # get even PTE entry 1466 _SLL k0, k0, WIRED_SHIFT 1467 mfc0 k1, MIPS_COP_0_TLB_INDEX 1468 _SRL k0, k0, WIRED_SHIFT 1469 sltiu k1, k1, MIPS3_TLB_WIRED_UPAGES # Luckily this is MIPS3_PG_G 1470 or k1, k1, k0 1471 _MTC0 k0, MIPS_COP_0_TLB_LO0 # save PTE entry 1472 COP0_SYNC 1473 nop 1474 nop # required for QED5230 1475 tlbwi # update TLB 1476 COP0_SYNC 1477 nop 1478 nop 1479 nop 1480 nop 1481 nop 1482 eret 1483END(MIPSX(TLBInvalidException)) 1484 1485/*---------------------------------------------------------------------------- 1486 * 1487 * mipsN_TLBMissException -- 1488 * 1489 * Handle a TLB miss exception from kernel mode in kernel space. 1490 * The BaddVAddr, Context, and EntryHi registers contain the failed 1491 * virtual address. 1492 * 1493 * Results: 1494 * None. 1495 * 1496 * Side effects: 1497 * None. 1498 * 1499 *---------------------------------------------------------------------------- 1500 */ 1501LEAF_NOPROFILE(MIPSX(TLBMissException)) 1502 .set noat 1503 _MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address 1504 li k1, VM_MIN_KERNEL_ADDRESS # compute index 1505 subu k0, k0, k1 1506 lw k1, _C_LABEL(Sysmapsize) # index within range? 1507 srl k0, k0, PGSHIFT 1508 sltu k1, k0, k1 1509#ifdef newsmips 1510 /* news5000 has ROM work area at 0xfff00000. */ 1511 bne k1, zero, 1f 1512 nop 1513 j checkromwork 15141: 1515#else 1516 beq k1, zero, outofworld # No. Failing beyond. . . 1517#endif 1518 lw k1, _C_LABEL(Sysmap) 1519 srl k0, k0, 1 1520 sll k0, k0, 3 # compute offset from index 1521 addu k1, k1, k0 1522 lw k0, 0(k1) # get PTE entry 1523 lw k1, 4(k1) # get odd PTE entry 1524 _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit 1525 _SRL k0, k0, WIRED_SHIFT 1526 _MTC0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry 1527 COP0_SYNC 1528 _SLL k1, k1, WIRED_SHIFT 1529 _SRL k1, k1, WIRED_SHIFT 1530 _MTC0 k1, MIPS_COP_0_TLB_LO1 # load PTE entry 1531 COP0_SYNC 1532 nop 1533 nop # required for QED5230 1534 tlbwr # write TLB 1535 COP0_SYNC 1536 nop 1537 nop 1538 nop 1539 nop 1540 nop 1541 eret 1542 1543outofworld: 1544 /* eret to panic so shutdown can use K2. Try to ensure valid $sp. */ 1545 la a0,_C_LABEL(panic) 1546 _MFC0 a2, MIPS_COP_0_EXC_PC 1547 move a1, sp 1548 sll k0, k0, PGSHIFT 1549 _MTC0 a0, MIPS_COP_0_EXC_PC # return to panic 1550 COP0_SYNC 1551 li k1, VM_MIN_KERNEL_ADDRESS 1552 addu a3, k0, k1 1553#if defined(DDB) 1554 bltz sp, 1f # for ddb try to keep frame 1555 nop 1556#endif 1557 la sp, start # set sp to a valid place 15581: la a0, 9f # string 1559 eret 1560 1561 .set at 1562END(MIPSX(TLBMissException)) 1563 1564 MSG("TLB out of universe: ksp %p epc %p vaddr %p") 1565 1566/* 1567 * Mark where code entered from exception hander jumptable 1568 * ends, for stack traceback code. 1569 */ 1570 1571 .globl _C_LABEL(MIPSX(exceptionentry_end)) 1572_C_LABEL(MIPSX(exceptionentry_end)): 1573 1574/*-------------------------------------------------------------------------- 1575 * 1576 * mipsN_SetPID -- 1577 * 1578 * Write the given pid into the TLB pid reg. 1579 * 1580 * mips3_SetPID(pid) 1581 * int pid; 1582 * 1583 * Results: 1584 * None. 1585 * 1586 * Side effects: 1587 * PID set in the entry hi register. 1588 * 1589 *-------------------------------------------------------------------------- 1590 */ 1591LEAF(MIPSX(SetPID)) 1592 _MTC0 a0, MIPS_COP_0_TLB_HI # Write the hi reg value 1593 COP0_SYNC 1594 /* XXX simonb: lose these nops for mips32/64? */ 1595 nop # required for QED5230 1596 nop # required for QED5230 1597 j ra 1598 nop 1599END(MIPSX(SetPID)) 1600 1601/*-------------------------------------------------------------------------- 1602 * 1603 * mipsN_TLBUpdate -- 1604 * 1605 * Update the TLB if highreg is found; otherwise, enter the data. 1606 * 1607 * mips3_TLBUpdate(virpageadr, lowregx) 1608 * unsigned virpageadr, lowregx; 1609 * 1610 * Results: 1611 * < 0 if loaded >= 0 if updated. 1612 * 1613 * Side effects: 1614 * None. 1615 * 1616 *-------------------------------------------------------------------------- 1617 */ 1618LEAF(MIPSX(TLBUpdate)) 1619 mfc0 v1, MIPS_COP_0_STATUS # Save the status register. 1620 mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts 1621 COP0_SYNC 1622 and t1, a0, MIPS3_PG_ODDPG # t1 = Even/Odd flag 1623 li v0, (MIPS3_PG_HVPN | MIPS3_PG_ASID) 1624 and a0, a0, v0 1625 _MFC0 t0, MIPS_COP_0_TLB_HI # Save current PID 1626 _MTC0 a0, MIPS_COP_0_TLB_HI # Init high reg 1627 COP0_SYNC 1628 and a2, a1, MIPS3_PG_G # Copy global bit 1629 nop 1630 nop 1631 tlbp # Probe for the entry. 1632 COP0_SYNC 1633 _SLL a1, a1, WIRED_SHIFT # Clear top 34 bits of EntryLo 1634 _SRL a1, a1, WIRED_SHIFT 1635 bne t1, zero, 2f # Decide even odd 1636 mfc0 v0, MIPS_COP_0_TLB_INDEX # See what we got 1637# EVEN 1638 nop 1639 bltz v0, 1f # index < 0 => !found 1640 nop 1641 nop # required for QED5230 1642 1643 tlbr # update, read entry first 1644 COP0_SYNC 1645 nop 1646 nop 1647 nop 1648 _MTC0 a1, MIPS_COP_0_TLB_LO0 # init low reg0. 1649 COP0_SYNC 1650 nop 1651 nop # required for QED5230 1652 tlbwi # update slot found 1653 COP0_SYNC 1654 nop # required for QED5230 1655 nop # required for QED5230 1656 b 4f 1657 nop 16581: 1659#if defined(MIPS3) && defined(MIPS3_4100) /* VR4100 core */ 1660 lw v0, _C_LABEL(default_pg_mask) # default_pg_mask declared 1661 mtc0 v0, MIPS_COP_0_TLB_PG_MASK # in mips_machdep.c 1662#else 1663 mtc0 zero, MIPS_COP_0_TLB_PG_MASK # init mask. 1664#endif 1665 COP0_SYNC 1666 _MTC0 a0, MIPS_COP_0_TLB_HI # init high reg. 1667 COP0_SYNC 1668 _MTC0 a1, MIPS_COP_0_TLB_LO0 # init low reg0. 1669 COP0_SYNC 1670 _MTC0 a2, MIPS_COP_0_TLB_LO1 # init low reg1. 1671 COP0_SYNC 1672 nop 1673 nop # required for QED5230 1674 tlbwr # enter into a random slot 1675 COP0_SYNC 1676 nop # required for QED5230 1677 nop # required for QED5230 1678 b 4f 1679 nop 1680# ODD 16812: 1682 nop 1683 bltz v0, 3f # index < 0 => !found 1684 nop 1685 nop # required for QED5230 1686 1687 tlbr # read the entry first 1688 COP0_SYNC 1689 nop 1690 nop 1691 nop 1692 _MTC0 a1, MIPS_COP_0_TLB_LO1 # init low reg1. 1693 COP0_SYNC 1694 nop 1695 nop # required for QED5230 1696 tlbwi # update slot found 1697 COP0_SYNC 1698 nop # required for QED5230 1699 nop # required for QED5230 1700 b 4f 1701 nop 17023: 1703#if defined(MIPS3) && defined(MIPS3_4100) /* VR4100 core */ 1704 lw v0, _C_LABEL(default_pg_mask) # default_pg_mask declared 1705 mtc0 v0, MIPS_COP_0_TLB_PG_MASK # in mips_machdep.c 1706#else 1707 mtc0 zero, MIPS_COP_0_TLB_PG_MASK # init mask. 1708#endif 1709 COP0_SYNC 1710 _MTC0 a0, MIPS_COP_0_TLB_HI # init high reg. 1711 COP0_SYNC 1712 _MTC0 a2, MIPS_COP_0_TLB_LO0 # init low reg0. 1713 COP0_SYNC 1714 _MTC0 a1, MIPS_COP_0_TLB_LO1 # init low reg1. 1715 COP0_SYNC 1716 nop 1717 nop # required for QED5230 1718 tlbwr # enter into a random slot 1719 COP0_SYNC 17204: # Make shure pipeline 1721 nop # advances before we 1722 nop # uses the tlb. 1723 nop 1724 nop 1725 _MTC0 t0, MIPS_COP_0_TLB_HI # restore PID 1726 COP0_SYNC 1727 nop # required for QED5230 1728 nop # required for QED5230 1729 j ra 1730 mtc0 v1, MIPS_COP_0_STATUS # Restore the status register 1731 COP0_SYNC # XXXX - not executed!! 1732END(MIPSX(TLBUpdate)) 1733 1734/*-------------------------------------------------------------------------- 1735 * 1736 * mipsN_TLBRead -- 1737 * 1738 * Read the TLB entry. 1739 * 1740 * mips3_TLBRead(entry, tlb) 1741 * unsigned entry; 1742 * struct tlb *tlb; 1743 * 1744 * Results: 1745 * None. 1746 * 1747 * Side effects: 1748 * tlb will contain the TLB entry found. 1749 * 1750 *-------------------------------------------------------------------------- 1751 */ 1752LEAF(MIPSX(TLBRead)) 1753 mfc0 v1, MIPS_COP_0_STATUS # Save the status register. 1754 mtc0 zero, MIPS_COP_0_STATUS # Disable interrupts 1755 COP0_SYNC 1756 nop 1757 mfc0 t6, MIPS_COP_0_TLB_PG_MASK # save current pgMask 1758 nop 1759 _MFC0 t0, MIPS_COP_0_TLB_HI # Get current PID 1760 1761 mtc0 a0, MIPS_COP_0_TLB_INDEX # Set the index register 1762 COP0_SYNC 1763 nop 1764 nop # required for QED5230 1765 tlbr # Read from the TLB 1766 COP0_SYNC 1767 nop 1768 nop 1769 nop 1770 mfc0 t2, MIPS_COP_0_TLB_PG_MASK # fetch the pgMask 1771 _MFC0 t3, MIPS_COP_0_TLB_HI # fetch the hi entry 1772 _MFC0 t4, MIPS_COP_0_TLB_LO0 # See what we got 1773 _MFC0 t5, MIPS_COP_0_TLB_LO1 # See what we got 1774 _MTC0 t0, MIPS_COP_0_TLB_HI # restore PID 1775 COP0_SYNC 1776 mtc0 t6, MIPS_COP_0_TLB_PG_MASK # restore pgMask 1777 COP0_SYNC 1778 nop 1779 nop 1780 nop # wait for PID active 1781 mtc0 v1, MIPS_COP_0_STATUS # Restore the status register 1782 COP0_SYNC 1783 nop 1784 sw t2, 0(a1) 1785 sw t3, 4(a1) 1786 sw t4, 8(a1) 1787 j ra 1788 sw t5, 12(a1) 1789END(MIPSX(TLBRead)) 1790 1791#if defined(MIPS3) && !defined(MIPS3_5900) 1792/*---------------------------------------------------------------------------- 1793 * 1794 * mips3_VCED -- 1795 * 1796 * Handle virtual coherency exceptions. 1797 * Called directly from the mips3 execption-table code. 1798 * only k0, k1 are avaiable on entry 1799 * 1800 * Results: 1801 * None. 1802 * 1803 * Side effects: 1804 * Remaps the conflicting address as uncached and returns 1805 * from the execption. 1806 * 1807 * NB: cannot be profiled, all registers are user registers on entry. 1808 * 1809 *---------------------------------------------------------------------------- 1810 */ 1811LEAF_NOPROFILE(MIPSX(VCED)) 1812 .set noat 1813 mfc0 k0, MIPS_COP_0_BAD_VADDR # fault addr. 1814 li k1, -16 1815 and k0, k1 1816 cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) 1817 cache (CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0) 1818#ifdef DEBUG 1819 mfc0 k0, MIPS_COP_0_BAD_VADDR 1820 la k1, VCED_vaddr 1821 sw k0, 0(k1) 1822 mfc0 k0, MIPS_COP_0_EXC_PC 1823 la k1, VCED_epc 1824 sw k0, 0(k1) 1825 la k1, VCED_count # count number of exceptions 1826 srl k0, k0, 26 # position upper 4 bits of VA 1827 and k0, k0, 0x3c # mask it off 1828 add k1, k0 # get address of count table 1829 lw k0, 0(k1) 1830 addu k0, 1 1831 sw k0, 0(k1) 1832#endif 1833 eret 1834 .set at 1835 1836#ifdef DEBUG 1837 .data 1838 .globl _C_LABEL(VCED_count) 1839_C_LABEL(VCED_count): 1840 .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1841 .globl _C_LABEL(VCED_epc) 1842_C_LABEL(VCED_epc): 1843 .word 0 1844 .globl _C_LABEL(VCED_vaddr) 1845_C_LABEL(VCED_vaddr): 1846 .word 0 1847 .text 1848#endif 1849END(MIPSX(VCED)) 1850 1851LEAF_NOPROFILE(MIPSX(VCEI)) 1852 .set noat 1853 mfc0 k0, MIPS_COP_0_BAD_VADDR # fault addr. 1854 cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) 1855 cache (CACHE_R4K_I | CACHEOP_R4K_HIT_INV), 0(k0) 1856#ifdef DEBUG 1857 mfc0 k0, MIPS_COP_0_BAD_VADDR 1858 la k1, VCEI_vaddr 1859 sw k0, 0(k1) 1860 la k1, VCEI_count # count number of exceptions 1861 srl k0, k0, 26 # position upper 4 bits of VA 1862 and k0, k0, 0x3c # mask it off 1863 add k1, k0 # get address of count table 1864 lw k0, 0(k1) 1865 addu k0, 1 1866 sw k0, 0(k1) 1867#endif 1868 eret 1869 .set at 1870 1871#ifdef DEBUG 1872 .data 1873 .globl _C_LABEL(VCEI_count) 1874_C_LABEL(VCEI_count): 1875 .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1876 .globl _C_LABEL(VCEI_vaddr) 1877_C_LABEL(VCEI_vaddr): 1878 .word 0 1879 .text 1880#endif 1881END(MIPSX(VCEI)) 1882#endif /* MIPS3 && !MIPS3_5900 */ 1883 1884/* 1885 * mipsN_proc_trampoline() 1886 * 1887 * Arrange for a function to be invoked neatly, after a cpu_switch(). 1888 * Call the service function with one argument, specified by the s0 1889 * and s1 respectively. There is no need register save operation. 1890 */ 1891LEAF(MIPSX(proc_trampoline)) 1892 jal ra, s0 1893 move a0, s1 1894 .set noat 1895 # 1896 # Make sure to disable interrupts here, as otherwise 1897 # we can take an interrupt *after* EXL is set, and 1898 # end up returning to a bogus PC since the PC is not 1899 # saved if EXL=1. 1900 # 1901 mtc0 zero, MIPS_COP_0_STATUS # disable int 1902 COP0_SYNC 1903 nop # 3 op delay 1904 nop 1905 nop 1906 li a0, MIPS_SR_EXL # set exception level 1907 mtc0 a0, MIPS_COP_0_STATUS 1908 COP0_SYNC 1909 nop 1910 nop 1911 addu a1, sp, CALLFRAME_SIZ 1912 # REG_L a0, FRAME_SR(a1) 1913 REG_L t0, FRAME_MULLO(a1) 1914 REG_L t1, FRAME_MULHI(a1) 1915 REG_L v0, FRAME_EPC(a1) 1916 mtlo t0 1917 mthi t1 1918 _MTC0 v0, MIPS_COP_0_EXC_PC 1919 COP0_SYNC 1920 nop 1921 move k1, a1 1922#ifdef IPL_ICU_MASK 1923 .set at 1924 lw t0, FRAME_PPL(k1) 1925 sw t0, _C_LABEL(md_imask) 1926 jal _C_LABEL(md_imask_update) 1927 nop 1928 .set noat 1929#endif 1930 REG_L AT, FRAME_AST(k1) 1931 REG_L v0, FRAME_V0(k1) 1932 REG_L v1, FRAME_V1(k1) 1933 REG_L a0, FRAME_A0(k1) 1934 REG_L a1, FRAME_A1(k1) 1935 REG_L a2, FRAME_A2(k1) 1936 REG_L a3, FRAME_A3(k1) 1937 REG_L t0, FRAME_T0(k1) 1938 REG_L t1, FRAME_T1(k1) 1939 REG_L t2, FRAME_T2(k1) 1940 REG_L t3, FRAME_T3(k1) 1941 REG_L t4, FRAME_T4(k1) 1942 REG_L t5, FRAME_T5(k1) 1943 REG_L t6, FRAME_T6(k1) 1944 REG_L t7, FRAME_T7(k1) 1945 REG_L s0, FRAME_S0(k1) 1946 REG_L s1, FRAME_S1(k1) 1947 REG_L s2, FRAME_S2(k1) 1948 REG_L s3, FRAME_S3(k1) 1949 REG_L s4, FRAME_S4(k1) 1950 REG_L s5, FRAME_S5(k1) 1951 REG_L s6, FRAME_S6(k1) 1952 REG_L s7, FRAME_S7(k1) 1953 REG_L t8, FRAME_T8(k1) 1954 REG_L t9, FRAME_T9(k1) 1955 REG_L k0, FRAME_SR(k1) 1956 DYNAMIC_STATUS_MASK(k0,sp) # machine dependent masking 1957 REG_L gp, FRAME_GP(k1) 1958 REG_L s8, FRAME_S8(k1) 1959 REG_L ra, FRAME_RA(k1) 1960 REG_L sp, FRAME_SP(k1) 1961 mtc0 k0, MIPS_COP_0_STATUS 1962 COP0_SYNC 1963 nop 1964 nop 1965 eret 1966 .set at 1967END(MIPSX(proc_trampoline)) 1968 1969/* 1970 * void mipsN_cpu_switch_resume(struct proc *newproc) 1971 * 1972 * Wiredown the USPACE of newproc in TLB entry#0. Check whether target 1973 * USPACE is already in another place of TLB before that, and make 1974 * sure TBIS(it) in the case. 1975 */ 1976LEAF_NOPROFILE(MIPSX(cpu_switch_resume)) 1977 lw a1, P_MD_UPTE_0(a0) # a1 = upte[0] 1978 lw a2, P_MD_UPTE_1(a0) # a2 = upte[1] 1979 lw v0, P_ADDR(a0) # va = p->p_addr 1980 li s0, MIPS_KSEG2_START 1981 blt v0, s0, resume 1982 nop 1983 1984 and s0, v0, MIPS3_PG_ODDPG 1985 beq s0, zero, entry0 1986 nop 1987 1988 PANIC("USPACE sat on odd page boundary") 1989 1990entry0: 1991 _MTC0 v0, MIPS_COP_0_TLB_HI # VPN = va 1992 COP0_SYNC 1993 nop 1994 nop 1995 tlbp # probe VPN 1996 COP0_SYNC 1997 nop 1998 nop 1999 mfc0 s0, MIPS_COP_0_TLB_INDEX 2000 nop 2001 bltz s0, entry0set 2002 sll s0, s0, 13 # PAGE_SHIFT + 1 2003 la s0, MIPS_KSEG0_START(s0) 2004 _MTC0 s0, MIPS_COP_0_TLB_HI 2005 COP0_SYNC 2006 _MTC0 zero, MIPS_COP_0_TLB_LO0 2007 COP0_SYNC 2008 _MTC0 zero, MIPS_COP_0_TLB_LO1 2009 COP0_SYNC 2010 nop 2011 nop 2012 tlbwi 2013 COP0_SYNC 2014 nop 2015 nop 2016 _MTC0 v0, MIPS_COP_0_TLB_HI # set VPN again 2017 COP0_SYNC 2018entry0set: 2019 mtc0 zero, MIPS_COP_0_TLB_INDEX # TLB entry #0 2020 COP0_SYNC 2021 or a1, MIPS3_PG_G 2022 _MTC0 a1, MIPS_COP_0_TLB_LO0 # upte[0] | PG_G 2023 COP0_SYNC 2024 or a2, MIPS3_PG_G 2025 _MTC0 a2, MIPS_COP_0_TLB_LO1 # upte[1] | PG_G 2026 COP0_SYNC 2027 nop 2028 nop 2029 tlbwi # set TLB entry #0 2030 COP0_SYNC 2031 nop 2032 nop 2033 2034resume: 2035 j ra 2036 nop 2037END(MIPSX(cpu_switch_resume)) 2038 2039/* 2040 * void mipsN_TBIS(vaddr_t va) 2041 * 2042 * Invalidate a TLB entry which has the given vaddr and ASID if found. 2043 */ 2044LEAF_NOPROFILE(MIPSX(TBIS)) 2045 mfc0 v1, MIPS_COP_0_STATUS # save status register 2046 mtc0 zero, MIPS_COP_0_STATUS # disable interrupts 2047 COP0_SYNC 2048 2049 li v0, (MIPS3_PG_HVPN | MIPS3_PG_ASID) 2050 _MFC0 t0, MIPS_COP_0_TLB_HI # save current ASID 2051 mfc0 t3, MIPS_COP_0_TLB_PG_MASK # save current pgMask 2052 and a0, a0, v0 # make sure valid entryHi 2053 _MTC0 a0, MIPS_COP_0_TLB_HI # look for the vaddr & ASID 2054 COP0_SYNC 2055 nop 2056 nop 2057 tlbp # probe the entry in question 2058 COP0_SYNC 2059 nop 2060 nop 2061 mfc0 v0, MIPS_COP_0_TLB_INDEX # see what we got 2062 #nop # -slip- 2063 #nop # -slip- 2064 bltz v0, 1f # index < 0 then skip 2065 li t1, MIPS_KSEG0_START # invalid address 2066 sll v0, v0, 13 # PAGE_SHIFT + 1 2067 addu t1, t1, v0 2068 _MTC0 t1, MIPS_COP_0_TLB_HI # make entryHi invalid 2069 COP0_SYNC 2070 _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 2071 COP0_SYNC 2072 _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 2073 COP0_SYNC 2074 mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask 2075 COP0_SYNC 2076 nop 2077 nop 2078 tlbwi 2079 COP0_SYNC 2080 nop 2081 nop 20821: 2083 _MTC0 t0, MIPS_COP_0_TLB_HI # restore current ASID 2084 COP0_SYNC 2085 mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask 2086 COP0_SYNC 2087 nop 2088 nop 2089 j ra 2090 mtc0 v1, MIPS_COP_0_STATUS # restore status register 2091 COP0_SYNC # XXXX - not executed!! 2092END(MIPSX(TBIS)) 2093 2094/* 2095 * void mips3_TBIAP(int sizeofTLB) 2096 * 2097 * Invalidate TLB entries belong to per process user spaces while 2098 * leaving entries for kernel space marked global intact. 2099 */ 2100LEAF_NOPROFILE(MIPSX(TBIAP)) 2101 mfc0 v1, MIPS_COP_0_STATUS # save status register 2102 mtc0 zero, MIPS_COP_0_STATUS # disable interrupts 2103 COP0_SYNC 2104 2105 move t2, a0 2106 mfc0 t1, MIPS_COP_0_TLB_WIRED 2107 li v0, MIPS_KSEG0_START # invalid address 2108 mfc0 t3, MIPS_COP_0_TLB_PG_MASK # save current pgMask 2109 2110 # do {} while (t1 < t2) 21111: 2112 mtc0 t1, MIPS_COP_0_TLB_INDEX # set index 2113 COP0_SYNC 2114 sll t4, t1, 13 # PAGE_SHIFT + 1 2115 nop 2116 /* XXX simonb: lose this nop for mips32/64? */ 2117 nop 2118 tlbr # obtain an entry 2119 COP0_SYNC 2120 /* XXX simonb: lose these nops for mips32/64? */ 2121 nop 2122 nop 2123 nop 2124 _MFC0 a0, MIPS_COP_0_TLB_LO1 2125 and a0, a0, MIPS3_PG_G # check to see it has G bit 2126 bnez a0, 2f 2127 addu t4, t4, v0 2128 2129 _MTC0 t4, MIPS_COP_0_TLB_HI # make entryHi invalid 2130 COP0_SYNC 2131 _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 2132 COP0_SYNC 2133 _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 2134 COP0_SYNC 2135 mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out mask entry 2136 COP0_SYNC 2137 /* XXX simonb: lose these nops for mips32/64? */ 2138 nop 2139 nop 2140 tlbwi # invalidate the TLB entry 2141 COP0_SYNC 21422: 2143 addu t1, t1, 1 2144 bne t1, t2, 1b 2145 nop 2146 2147 mtc0 t3, MIPS_COP_0_TLB_PG_MASK # restore pgMask 2148 COP0_SYNC 2149 /* XXX simonb: lose these nops for mips32/64? */ 2150 nop 2151 nop 2152 j ra # new ASID will be set soon 2153 mtc0 v1, MIPS_COP_0_STATUS # restore status register 2154 COP0_SYNC # XXXX - not executed!! 2155END(MIPSX(TBIAP)) 2156 2157/* 2158 * void mipsN_TBIA(int sizeofTLB) 2159 * 2160 * Invalidate all of non-wired TLB entries. 2161 */ 2162LEAF_NOPROFILE(MIPSX(TBIA)) 2163 mfc0 v1, MIPS_COP_0_STATUS # save status register 2164 mtc0 zero, MIPS_COP_0_STATUS # disable interrupts 2165 COP0_SYNC 2166 2167 li v0, MIPS_KSEG0_START # invalid address 2168 _MFC0 t0, MIPS_COP_0_TLB_HI # save current ASID 2169 mfc0 t1, MIPS_COP_0_TLB_WIRED 2170 mfc0 t2, MIPS_COP_0_TLB_PG_MASK # save current pgMask 2171 2172 _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 2173 COP0_SYNC 2174 _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 2175 COP0_SYNC 2176 mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask 2177 COP0_SYNC 2178 2179 # do {} while (t1 < a0) 21801: 2181 mtc0 t1, MIPS_COP_0_TLB_INDEX # set TLBindex 2182 COP0_SYNC 2183 sll t4, t1, 13 # PAGE_SHIFT + 1 2184 add t4, v0, t4 2185 _MTC0 t4, MIPS_COP_0_TLB_HI # make entryHi invalid 2186 COP0_SYNC 2187 nop 2188 nop 2189 tlbwi # clear the entry 2190 COP0_SYNC 2191 addu t1, t1, 1 # increment index 2192 bne t1, a0, 1b 2193 nop 2194 2195 _MTC0 t0, MIPS_COP_0_TLB_HI # restore ASID 2196 COP0_SYNC 2197 mtc0 t2, MIPS_COP_0_TLB_PG_MASK # restore pgMask 2198 COP0_SYNC 2199 nop 2200 nop 2201 j ra 2202 mtc0 v1, MIPS_COP_0_STATUS # restore status register 2203 COP0_SYNC # XXXX - not executed!! 2204END(MIPSX(TBIA)) 2205 2206 .data 2207 2208 .globl _C_LABEL(MIPSX(locoresw)) 2209_C_LABEL(MIPSX(locoresw)): 2210 .word _C_LABEL(MIPSX(cpu_switch_resume)) 2211 .word _C_LABEL(MIPSX(proc_trampoline)) 2212 .word _C_LABEL(mips_idle) 2213 2214MIPSX(excpt_sw): 2215 #### 2216 #### The kernel exception handlers. 2217 #### 2218 .word _C_LABEL(MIPSX(KernIntr)) # 0 external interrupt 2219 .word _C_LABEL(MIPSX(KernGenException)) # 1 TLB modification 2220 .word _C_LABEL(MIPSX(TLBInvalidException))# 2 TLB miss (LW/I-fetch) 2221 .word _C_LABEL(MIPSX(TLBInvalidException))# 3 TLB miss (SW) 2222 .word _C_LABEL(MIPSX(KernGenException)) # 4 address error (LW/I-fetch) 2223 .word _C_LABEL(MIPSX(KernGenException)) # 5 address error (SW) 2224 .word _C_LABEL(MIPSX(KernGenException)) # 6 bus error (I-fetch) 2225 .word _C_LABEL(MIPSX(KernGenException)) # 7 bus error (load or store) 2226 .word _C_LABEL(MIPSX(KernGenException)) # 8 system call 2227 .word _C_LABEL(MIPSX(KernGenException)) # 9 breakpoint 2228 .word _C_LABEL(MIPSX(KernGenException)) # 10 reserved instruction 2229 .word _C_LABEL(MIPSX(KernGenException)) # 11 coprocessor unusable 2230 .word _C_LABEL(MIPSX(KernGenException)) # 12 arithmetic overflow 2231 .word _C_LABEL(MIPSX(KernGenException)) # 13 r4k trap exception 2232#if defined(MIPS3) && !defined(MIPS3_5900) 2233 .word _C_LABEL(mips3_VCEI) # 14 r4k virt coherence 2234#else 2235 .word _C_LABEL(MIPSX(KernGenException)) # 14 reserved 2236#endif 2237 .word _C_LABEL(MIPSX(KernGenException)) # 15 r4k FP exception 2238 .word _C_LABEL(MIPSX(KernGenException)) # 16 reserved 2239 .word _C_LABEL(MIPSX(KernGenException)) # 17 reserved 2240 .word _C_LABEL(MIPSX(KernGenException)) # 18 reserved 2241 .word _C_LABEL(MIPSX(KernGenException)) # 19 reserved 2242 .word _C_LABEL(MIPSX(KernGenException)) # 20 reserved 2243 .word _C_LABEL(MIPSX(KernGenException)) # 21 reserved 2244 .word _C_LABEL(MIPSX(KernGenException)) # 22 reserved 2245 .word _C_LABEL(MIPSX(KernGenException)) # 23 watch exception 2246 .word _C_LABEL(MIPSX(KernGenException)) # 24 reserved 2247 .word _C_LABEL(MIPSX(KernGenException)) # 25 reserved 2248 .word _C_LABEL(MIPSX(KernGenException)) # 26 reserved 2249 .word _C_LABEL(MIPSX(KernGenException)) # 27 reserved 2250 .word _C_LABEL(MIPSX(KernGenException)) # 28 reserved 2251 .word _C_LABEL(MIPSX(KernGenException)) # 29 reserved 2252 .word _C_LABEL(MIPSX(KernGenException)) # 30 reserved 2253#if defined(MIPS3) && !defined(MIPS3_5900) 2254 .word _C_LABEL(mips3_VCED) # 31 v. coherence exception data 2255#else 2256 .word _C_LABEL(MIPSX(KernGenException)) # 31 reserved 2257#endif 2258 ##### 2259 ##### The user exception handlers. 2260 ##### 2261 .word _C_LABEL(MIPSX(UserIntr)) # 0 2262 .word _C_LABEL(MIPSX(UserGenException)) # 1 2263 .word _C_LABEL(MIPSX(UserGenException)) # 2 2264 .word _C_LABEL(MIPSX(UserGenException)) # 3 2265 .word _C_LABEL(MIPSX(UserGenException)) # 4 2266 .word _C_LABEL(MIPSX(UserGenException)) # 5 2267 .word _C_LABEL(MIPSX(UserGenException)) # 6 2268 .word _C_LABEL(MIPSX(UserGenException)) # 7 2269 .word _C_LABEL(MIPSX(SystemCall)) # 8 2270 .word _C_LABEL(MIPSX(UserGenException)) # 9 2271 .word _C_LABEL(MIPSX(UserGenException)) # 10 2272 .word _C_LABEL(MIPSX(UserGenException)) # 11 2273 .word _C_LABEL(MIPSX(UserGenException)) # 12 2274 .word _C_LABEL(MIPSX(UserGenException)) # 13 2275#if defined(MIPS3) && !defined(MIPS3_5900) 2276 .word _C_LABEL(mips3_VCEI) # 14 2277#else 2278 .word _C_LABEL(MIPSX(UserGenException)) # 14 2279#endif 2280 .word _C_LABEL(MIPSX(UserGenException)) # 15 2281 .word _C_LABEL(MIPSX(UserGenException)) # 16 2282 .word _C_LABEL(MIPSX(UserGenException)) # 17 2283 .word _C_LABEL(MIPSX(UserGenException)) # 18 2284 .word _C_LABEL(MIPSX(UserGenException)) # 19 2285 .word _C_LABEL(MIPSX(UserGenException)) # 20 2286 .word _C_LABEL(MIPSX(UserGenException)) # 21 2287 .word _C_LABEL(MIPSX(UserGenException)) # 22 2288 .word _C_LABEL(MIPSX(UserGenException)) # 23 2289 .word _C_LABEL(MIPSX(UserGenException)) # 24 2290 .word _C_LABEL(MIPSX(UserGenException)) # 25 2291 .word _C_LABEL(MIPSX(UserGenException)) # 26 2292 .word _C_LABEL(MIPSX(UserGenException)) # 27 2293 .word _C_LABEL(MIPSX(UserGenException)) # 28 2294 .word _C_LABEL(MIPSX(UserGenException)) # 29 2295 .word _C_LABEL(MIPSX(UserGenException)) # 30 2296#if defined(MIPS3) && !defined(MIPS3_5900) 2297 .word _C_LABEL(mips3_VCED) # 31 v. coherence exception data 2298#else 2299 .word _C_LABEL(MIPSX(UserGenException)) # 31 2300#endif 2301