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