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