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