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