| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: mipsX_subr.S,v 1.26.36.1.2.5 2009/09/02 15:56:52 matt Exp $ */ | | 1 | /* $NetBSD: mipsX_subr.S,v 1.26.36.1.2.6 2009/09/05 03:25:07 matt Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2002 Wasabi Systems, Inc. | | 4 | * Copyright 2002 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Simon Burge for Wasabi Systems, Inc. | | 7 | * Written by Simon Burge for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -296,54 +296,54 @@ | | | @@ -296,54 +296,54 @@ |
296 | * Vector code for the TLB-miss exception vector 0x80000000 | | 296 | * Vector code for the TLB-miss exception vector 0x80000000 |
297 | * on an r4000. | | 297 | * on an r4000. |
298 | * | | 298 | * |
299 | * This code is copied to the TLB exception vector address to | | 299 | * This code is copied to the TLB exception vector address to |
300 | * handle TLB translation misses. | | 300 | * handle TLB translation misses. |
301 | * NOTE: This code should be relocatable and max 32 instructions!!! | | 301 | * NOTE: This code should be relocatable and max 32 instructions!!! |
302 | * | | 302 | * |
303 | * Don't check for invalid pte's here. We load them as well and | | 303 | * Don't check for invalid pte's here. We load them as well and |
304 | * let the processor trap to load the correct value after service. | | 304 | * let the processor trap to load the correct value after service. |
305 | *---------------------------------------------------------------------------- | | 305 | *---------------------------------------------------------------------------- |
306 | */ | | 306 | */ |
307 | VECTOR(MIPSX(TLBMiss), unknown) | | 307 | VECTOR(MIPSX(TLBMiss), unknown) |
308 | .set noat | | 308 | .set noat |
309 | mfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address | | 309 | _MFC0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address |
310 | lui k1, %hi(segbase) #01: k1=hi of segbase | | 310 | lui k1, %hi(segbase) #01: k1=hi of segbase |
311 | bltz k0, 4f #02: k0<0 -> 4f (kernel fault) | | 311 | bltz k0, 4f #02: k0<0 -> 4f (kernel fault) |
312 | srl k0, (2*PGSHIFT-2-PTR_SCALESHIFT)#03: k0=seg offset (almost) | | 312 | PTR_SRL k0, (2*PGSHIFT-2-PTR_SCALESHIFT)#03: k0=seg offset (almost) |
313 | PTR_L k1, %lo(segbase)(k1) #04: k1=segment tab base | | 313 | PTR_L k1, %lo(segbase)(k1) #04: k1=segment tab base |
314 | andi k0, k0, (NBPG-(1<<PTR_SCALESHIFT))#05: k0=seg offset (mask 0x3) | | 314 | andi k0, k0, (NBPG-(1<<PTR_SCALESHIFT))#05: k0=seg offset (mask 0x3) |
315 | PTR_ADDU k1, k0, k1 #06: k1=seg entry address | | 315 | PTR_ADDU k1, k0, k1 #06: k1=seg entry address |
316 | PTR_L k1, 0(k1) #07: k1=seg entry | | 316 | PTR_L k1, 0(k1) #07: k1=seg entry |
317 | mfc0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) | | 317 | _MFC0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) |
318 | beq k1, zero, 5f #09: ==0 -- no page table | | 318 | beq k1, zero, 5f #09: ==0 -- no page table |
319 | srl k0, (PGSHIFT-2) #0a: k0=VPN (aka va>>10) | | 319 | PTR_SRL k0, (PGSHIFT-2) #0a: k0=VPN (aka va>>10) |
320 | andi k0, k0, (NBPG-8) #0b: k0=page tab offset | | 320 | andi k0, k0, (NBPG-8) #0b: k0=page tab offset |
321 | PTR_ADDU k1, k1, k0 #0c: k1=pte address | | 321 | PTR_ADDU k1, k1, k0 #0c: k1=pte address |
322 | INT_L k0, 0(k1) #0d: k0=lo0 pte | | 322 | INT_L k0, 0(k1) #0d: k0=lo0 pte |
323 | INT_L k1, 4(k1) #0e: k1=lo1 pte | | 323 | INT_L k1, 4(k1) #0e: k1=lo1 pte |
324 | sll k0, 2 #0f: chop top 2 bits (part 1a) | | 324 | PTR_SLL k0, 2 #0f: chop top 2 bits (part 1a) |
325 | srl k0, 2 #10: chop top 2 bits (part 1b) | | 325 | PTR_SRL k0, 2 #10: chop top 2 bits (part 1b) |
326 | #ifdef MIPS3_5900 | | 326 | #ifdef MIPS3_5900 |
327 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded | | 327 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded |
328 | sync.p #12: R5900 cop0 hazard | | 328 | sync.p #12: R5900 cop0 hazard |
329 | sll k1, 2 #13: chop top 2 bits (part 2a) | | 329 | PTR_SLL k1, 2 #13: chop top 2 bits (part 2a) |
330 | srl k1, 2 #14: chop top 2 bits (part 2b) | | 330 | PTR_SRL k1, 2 #14: chop top 2 bits (part 2b) |
331 | mtc0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded | | 331 | mtc0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded |
332 | sync.p #16: R5900 cop0 hazard | | 332 | sync.p #16: R5900 cop0 hazard |
333 | #else /* MIPS3_5900 */ | | 333 | #else /* MIPS3_5900 */ |
334 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded | | 334 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded |
335 | sll k1, 2 #12: chop top 2 bits (part 2a) | | 335 | PTR_SLL k1, 2 #12: chop top 2 bits (part 2a) |
336 | srl k1, 2 #13: chop top 2 bits (part 2b) | | 336 | PTR_SRL k1, 2 #13: chop top 2 bits (part 2b) |
337 | mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded | | 337 | mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded |
338 | nop #15: standard nop | | 338 | nop #15: standard nop |
339 | nop #16: extra nop for QED5230 | | 339 | nop #16: extra nop for QED5230 |
340 | #endif /* MIPS3_5900 */ | | 340 | #endif /* MIPS3_5900 */ |
341 | tlbwr #17: write to tlb | | 341 | tlbwr #17: write to tlb |
342 | nop #18: standard nop | | 342 | nop #18: standard nop |
343 | nop #19: needed by R4000/4400 | | 343 | nop #19: needed by R4000/4400 |
344 | nop #1a: needed by R4000/4400 | | 344 | nop #1a: needed by R4000/4400 |
345 | eret #1b: return from exception | | 345 | eret #1b: return from exception |
346 | 4: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception | | 346 | 4: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception |
347 | nop #1d: branch delay slot | | 347 | nop #1d: branch delay slot |
348 | 5: j slowfault #1e: no page table present | | 348 | 5: j slowfault #1e: no page table present |
349 | nop #1f: branch delay slot | | 349 | nop #1f: branch delay slot |
| @@ -361,43 +361,43 @@ _VECTOR_END(MIPSX(TLBMiss)) | | | @@ -361,43 +361,43 @@ _VECTOR_END(MIPSX(TLBMiss)) |
361 | * NOTE: This code should be relocatable and max 32 instructions!!! | | 361 | * NOTE: This code should be relocatable and max 32 instructions!!! |
362 | * | | 362 | * |
363 | * Note that we do not support the full size of the PTEs, relying | | 363 | * Note that we do not support the full size of the PTEs, relying |
364 | * on appropriate truncation/sign extension. | | 364 | * on appropriate truncation/sign extension. |
365 | * | | 365 | * |
366 | * Don't check for invalid pte's here. We load them as well and | | 366 | * Don't check for invalid pte's here. We load them as well and |
367 | * let the processor trap to load the correct value after service. | | 367 | * let the processor trap to load the correct value after service. |
368 | */ | | 368 | */ |
369 | VECTOR(MIPSX(XTLBMiss), unknown) | | 369 | VECTOR(MIPSX(XTLBMiss), unknown) |
370 | .set noat | | 370 | .set noat |
371 | dmfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address | | 371 | dmfc0 k0, MIPS_COP_0_BAD_VADDR #00: k0=bad address |
372 | lui k1, %hi(segbase) #01: k1=hi of segbase | | 372 | lui k1, %hi(segbase) #01: k1=hi of segbase |
373 | bltz k0, 4f #02: k0<0 -> 4f (kernel fault) | | 373 | bltz k0, 4f #02: k0<0 -> 4f (kernel fault) |
374 | srl k0, 2*PGSHIFT-2-PTR_SCALESHIFT #03: k0=seg offset (almost) | | 374 | PTR_SRL k0, 2*PGSHIFT-2-PTR_SCALESHIFT #03: k0=seg offset (almost) |
375 | PTR_L k1, %lo(segbase)(k1) #04: k1=segment tab base | | 375 | PTR_L k1, %lo(segbase)(k1) #04: k1=segment tab base |
376 | andi k0, NBPG-(1<<PTR_SCALESHIFT) #05: k0=seg offset (mask 0x3) | | 376 | andi k0, NBPG-(1<<PTR_SCALESHIFT) #05: k0=seg offset (mask 0x3) |
377 | PTR_ADDU k1, k0, k1 #06: k1=seg entry address | | 377 | PTR_ADDU k1, k0, k1 #06: k1=seg entry address |
378 | PTR_L k1, 0(k1) #07: k1=seg entry | | 378 | PTR_L k1, 0(k1) #07: k1=seg entry |
379 | dmfc0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) | | 379 | dmfc0 k0, MIPS_COP_0_BAD_VADDR #08: k0=bad address (again) |
380 | beq k1, zero, 5f #09: ==0 -- no page table | | 380 | beq k1, zero, 5f #09: ==0 -- no page table |
381 | srl k0, (PGSHIFT-2) #0a: k0=VPN (aka va>>10) | | 381 | PTR_SRL k0, (PGSHIFT-2) #0a: k0=VPN (aka va>>10) |
382 | andi k0, k0, (NBPG-8) #0b: k0=page tab offset | | 382 | andi k0, k0, (NBPG-8) #0b: k0=page tab offset |
383 | PTR_ADDU k1, k1, k0 #0c: k1=pte address | | 383 | PTR_ADDU k1, k1, k0 #0c: k1=pte address |
384 | INT_L k0, 0(k1) #0d: k0=lo0 pte | | 384 | INT_L k0, 0(k1) #0d: k0=lo0 pte |
385 | INT_L k1, 4(k1) #0e: k1=lo1 pte | | 385 | INT_L k1, 4(k1) #0e: k1=lo1 pte |
386 | sll k0, 2 #0f: chop top 2 bits (part 1a) | | 386 | PTR_SLL k0, 2 #0f: chop top 2 bits (part 1a) |
387 | srl k0, 2 #10: chop top 2 bits (part 1b) | | 387 | PTR_SRL k0, 2 #10: chop top 2 bits (part 1b) |
388 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded | | 388 | mtc0 k0, MIPS_COP_0_TLB_LO0 #11: lo0 is loaded |
389 | sll k1, 2 #12: chop top 2 bits (part 2a) | | 389 | PTR_SLL k1, 2 #12: chop top 2 bits (part 2a) |
390 | srl k1, 2 #13: chop top 2 bits (part 2b) | | 390 | PTR_SRL k1, 2 #13: chop top 2 bits (part 2b) |
391 | mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded | | 391 | mtc0 k1, MIPS_COP_0_TLB_LO1 #14: lo1 is loaded |
392 | nop #15: standard nop | | 392 | nop #15: standard nop |
393 | nop #16: extra nop for QED5230 | | 393 | nop #16: extra nop for QED5230 |
394 | tlbwr #17: write to tlb | | 394 | tlbwr #17: write to tlb |
395 | nop #18: standard nop | | 395 | nop #18: standard nop |
396 | nop #19: needed by R4000/4400 | | 396 | nop #19: needed by R4000/4400 |
397 | nop #1a: needed by R4000/4400 | | 397 | nop #1a: needed by R4000/4400 |
398 | eret #1b: return from exception | | 398 | eret #1b: return from exception |
399 | 4: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception | | 399 | 4: j _C_LABEL(MIPSX(TLBMissException)) #1c: kernel exception |
400 | nop #1d: branch delay slot | | 400 | nop #1d: branch delay slot |
401 | 5: j slowfault #1e: no page table present | | 401 | 5: j slowfault #1e: no page table present |
402 | nop #1f: branch delay slot | | 402 | nop #1f: branch delay slot |
403 | .set at | | 403 | .set at |
| @@ -442,38 +442,41 @@ _VECTOR_END(MIPSX(intr)) | | | @@ -442,38 +442,41 @@ _VECTOR_END(MIPSX(intr)) |
442 | VECTOR(MIPSX(exception), unknown) | | 442 | VECTOR(MIPSX(exception), unknown) |
443 | /* | | 443 | /* |
444 | * Find out what mode we came from and jump to the proper handler. | | 444 | * Find out what mode we came from and jump to the proper handler. |
445 | */ | | 445 | */ |
446 | .set noat | | 446 | .set noat |
447 | mfc0 k0, MIPS_COP_0_STATUS #00: get the status register | | 447 | mfc0 k0, MIPS_COP_0_STATUS #00: get the status register |
448 | mfc0 k1, MIPS_COP_0_CAUSE #01: get the cause register | | 448 | mfc0 k1, MIPS_COP_0_CAUSE #01: get the cause register |
449 | and k0, k0, MIPS3_SR_KSU_USER #02: test for user mode | | 449 | and k0, k0, MIPS3_SR_KSU_USER #02: test for user mode |
450 | # sneaky but the bits are | | 450 | # sneaky but the bits are |
451 | # with us........ | | 451 | # with us........ |
452 | sll k0, k0, 3 #03: shift user bit for cause index | | 452 | sll k0, k0, 3 #03: shift user bit for cause index |
453 | and k1, k1, MIPS3_CR_EXC_CODE #04: mask out the cause bits. | | 453 | and k1, k1, MIPS3_CR_EXC_CODE #04: mask out the cause bits. |
454 | or k1, k1, k0 #05: change index to user table | | 454 | or k1, k1, k0 #05: change index to user table |
| | | 455 | #ifdef _LP64 |
| | | 456 | PTR_SLL k1, k1, 1 |
| | | 457 | #endif |
455 | 1: | | 458 | 1: |
456 | PTR_LA k0, MIPSX(excpt_sw) #06: get base of the jump table | | 459 | PTR_LA k0, MIPSX(excpt_sw) #06: get base of the jump table |
457 | addu k0, k0, k1 #07: get the address of the | | 460 | PTR_ADDU k0, k0, k1 #08: get the address of the |
458 | # function entry. Note that | | 461 | # function entry. Note that |
459 | # the cause is already | | 462 | # the cause is already |
460 | # shifted left by 2 bits so | | 463 | # shifted left by 2 bits so |
461 | # we dont have to shift. | | 464 | # we dont have to shift. |
462 | PTR_L k0, 0(k0) #08: get the function address | | 465 | PTR_L k0, 0(k0) #09: get the function address |
463 | #nop # -slip- | | 466 | #nop # -slip- |
464 | | | 467 | |
465 | j k0 #09: jump to the function | | 468 | j k0 #0a: jump to the function |
466 | nop #0a: branch delay slot | | 469 | nop #0b: branch delay slot |
467 | .set at | | 470 | .set at |
468 | _VECTOR_END(MIPSX(exception)) | | 471 | _VECTOR_END(MIPSX(exception)) |
469 | | | 472 | |
470 | /*---------------------------------------------------------------------------- | | 473 | /*---------------------------------------------------------------------------- |
471 | * | | 474 | * |
472 | * slowfault -- | | 475 | * slowfault -- |
473 | * | | 476 | * |
474 | * Alternate entry point into the mips3_UserGenException or | | 477 | * Alternate entry point into the mips3_UserGenException or |
475 | * mips3_KernGenException, when the ULTB miss handler couldn't | | 478 | * mips3_KernGenException, when the ULTB miss handler couldn't |
476 | * find a TLB entry. | | 479 | * find a TLB entry. |
477 | * | | 480 | * |
478 | * Find out what mode we came from and call the appropriate handler. | | 481 | * Find out what mode we came from and call the appropriate handler. |
479 | * | | 482 | * |
| @@ -1433,46 +1436,46 @@ END(MIPSX(UserIntr)) | | | @@ -1433,46 +1436,46 @@ END(MIPSX(UserIntr)) |
1433 | * Results: | | 1436 | * Results: |
1434 | * None. | | 1437 | * None. |
1435 | * | | 1438 | * |
1436 | * Side effects: | | 1439 | * Side effects: |
1437 | * None. | | 1440 | * None. |
1438 | * | | 1441 | * |
1439 | *---------------------------------------------------------------------------- | | 1442 | *---------------------------------------------------------------------------- |
1440 | */ | | 1443 | */ |
1441 | LEAF_NOPROFILE(MIPSX(TLBInvalidException)) | | 1444 | LEAF_NOPROFILE(MIPSX(TLBInvalidException)) |
1442 | .set noat | | 1445 | .set noat |
1443 | _MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address | | 1446 | _MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address |
1444 | li k1, VM_MIN_KERNEL_ADDRESS # compute index | | 1447 | li k1, VM_MIN_KERNEL_ADDRESS # compute index |
1445 | bgez k0, _C_LABEL(MIPSX(KernGenException)) # full trap processing | | 1448 | bgez k0, _C_LABEL(MIPSX(KernGenException)) # full trap processing |
1446 | subu k0, k0, k1 | | 1449 | PTR_SUBU k0, k0, k1 |
1447 | INT_L k1, _C_LABEL(Sysmapsize) # index within range? | | 1450 | INT_L k1, _C_LABEL(Sysmapsize) # index within range? |
1448 | srl k0, k0, PGSHIFT | | 1451 | PTR_SRL k0, k0, PGSHIFT |
1449 | sltu k1, k0, k1 | | 1452 | sltu k1, k0, k1 |
1450 | beq k1, zero, outofworld # No. Failing beyond. . . | | 1453 | beq k1, zero, MIPSX(outofworld) # No. Failing beyond. . . |
1451 | nop # - delay slot - | | 1454 | nop # - delay slot - |
1452 | PTR_L k1, _C_LABEL(Sysmap) | | 1455 | PTR_L k1, _C_LABEL(Sysmap) |
1453 | | | 1456 | |
1454 | sll k0, k0, 2 # compute offset from index | | 1457 | PTR_SLL k0, k0, 2 # compute offset from index |
1455 | addu k1, k1, k0 | | 1458 | PTR_ADDU k1, k1, k0 |
1456 | tlbp # Probe the invalid entry | | 1459 | tlbp # Probe the invalid entry |
1457 | COP0_SYNC | | 1460 | COP0_SYNC |
1458 | and k0, k0, 4 # check even/odd page | | 1461 | and k0, k0, 4 # check even/odd page |
1459 | nop # required for QED 5230 | | 1462 | nop # required for QED 5230 |
1460 | bne k0, zero, KernTLBIOdd | | 1463 | bne k0, zero, KernTLBIOdd |
1461 | nop | | 1464 | nop |
1462 | | | 1465 | |
1463 | mfc0 k0, MIPS_COP_0_TLB_INDEX | | 1466 | mfc0 k0, MIPS_COP_0_TLB_INDEX |
1464 | nop | | 1467 | nop |
1465 | bltz k0, outofworld # ASSERT(TLB entry exists) | | 1468 | bltz k0, MIPSX(outofworld) # ASSERT(TLB entry exists) |
1466 | INT_L k0, 0(k1) # get PTE entry | | 1469 | INT_L k0, 0(k1) # get PTE entry |
1467 | | | 1470 | |
1468 | _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit | | 1471 | _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit |
1469 | _SRL k0, k0, WIRED_SHIFT | | 1472 | _SRL k0, k0, WIRED_SHIFT |
1470 | mtc0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry | | 1473 | mtc0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry |
1471 | COP0_SYNC | | 1474 | COP0_SYNC |
1472 | and k0, k0, MIPS3_PG_V # check for valid entry | | 1475 | and k0, k0, MIPS3_PG_V # check for valid entry |
1473 | nop # required for QED5230 | | 1476 | nop # required for QED5230 |
1474 | beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid | | 1477 | beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid |
1475 | INT_L k0, 4(k1) # get odd PTE entry | | 1478 | INT_L k0, 4(k1) # get odd PTE entry |
1476 | _SLL k0, k0, WIRED_SHIFT | | 1479 | _SLL k0, k0, WIRED_SHIFT |
1477 | mfc0 k1, MIPS_COP_0_TLB_INDEX | | 1480 | mfc0 k1, MIPS_COP_0_TLB_INDEX |
1478 | _SRL k0, k0, WIRED_SHIFT | | 1481 | _SRL k0, k0, WIRED_SHIFT |
| @@ -1484,27 +1487,27 @@ LEAF_NOPROFILE(MIPSX(TLBInvalidException | | | @@ -1484,27 +1487,27 @@ LEAF_NOPROFILE(MIPSX(TLBInvalidException |
1484 | nop # required for QED5230 | | 1487 | nop # required for QED5230 |
1485 | tlbwi # write TLB | | 1488 | tlbwi # write TLB |
1486 | COP0_SYNC | | 1489 | COP0_SYNC |
1487 | nop | | 1490 | nop |
1488 | nop | | 1491 | nop |
1489 | nop | | 1492 | nop |
1490 | nop | | 1493 | nop |
1491 | nop | | 1494 | nop |
1492 | eret | | 1495 | eret |
1493 | | | 1496 | |
1494 | KernTLBIOdd: | | 1497 | KernTLBIOdd: |
1495 | mfc0 k0, MIPS_COP_0_TLB_INDEX | | 1498 | mfc0 k0, MIPS_COP_0_TLB_INDEX |
1496 | nop | | 1499 | nop |
1497 | bltz k0, outofworld # assert(TLB Entry exists) | | 1500 | bltz k0, MIPSX(outofworld) # assert(TLB Entry exists) |
1498 | INT_L k0, 0(k1) # get PTE entry | | 1501 | INT_L k0, 0(k1) # get PTE entry |
1499 | | | 1502 | |
1500 | _SLL k0, k0, WIRED_SHIFT # get rid of wired bit | | 1503 | _SLL k0, k0, WIRED_SHIFT # get rid of wired bit |
1501 | _SRL k0, k0, WIRED_SHIFT | | 1504 | _SRL k0, k0, WIRED_SHIFT |
1502 | _MTC0 k0, MIPS_COP_0_TLB_LO1 # save PTE entry | | 1505 | _MTC0 k0, MIPS_COP_0_TLB_LO1 # save PTE entry |
1503 | COP0_SYNC | | 1506 | COP0_SYNC |
1504 | and k0, k0, MIPS3_PG_V # check for valid entry | | 1507 | and k0, k0, MIPS3_PG_V # check for valid entry |
1505 | nop # required for QED5230 | | 1508 | nop # required for QED5230 |
1506 | beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid | | 1509 | beq k0, zero, _C_LABEL(MIPSX(KernGenException)) # PTE invalid |
1507 | INT_L k0, -4(k1) # get even PTE entry | | 1510 | INT_L k0, -4(k1) # get even PTE entry |
1508 | _SLL k0, k0, WIRED_SHIFT | | 1511 | _SLL k0, k0, WIRED_SHIFT |
1509 | mfc0 k1, MIPS_COP_0_TLB_INDEX | | 1512 | mfc0 k1, MIPS_COP_0_TLB_INDEX |
1510 | _SRL k0, k0, WIRED_SHIFT | | 1513 | _SRL k0, k0, WIRED_SHIFT |
| @@ -1546,27 +1549,27 @@ LEAF_NOPROFILE(MIPSX(TLBMissException)) | | | @@ -1546,27 +1549,27 @@ LEAF_NOPROFILE(MIPSX(TLBMissException)) |
1546 | li k1, VM_MIN_KERNEL_ADDRESS # compute index | | 1549 | li k1, VM_MIN_KERNEL_ADDRESS # compute index |
1547 | PTR_SUBU k0, k0, k1 | | 1550 | PTR_SUBU k0, k0, k1 |
1548 | INT_L k1, _C_LABEL(Sysmapsize) # index within range? | | 1551 | INT_L k1, _C_LABEL(Sysmapsize) # index within range? |
1549 | PTR_SRL k0, k0, PGSHIFT | | 1552 | PTR_SRL k0, k0, PGSHIFT |
1550 | sltu k1, k0, k1 | | 1553 | sltu k1, k0, k1 |
1551 | #ifdef newsmips | | 1554 | #ifdef newsmips |
1552 | /* news5000 has ROM work area at 0xfff00000. */ | | 1555 | /* news5000 has ROM work area at 0xfff00000. */ |
1553 | bne k1, zero, 1f | | 1556 | bne k1, zero, 1f |
1554 | nop | | 1557 | nop |
1555 | j checkromwork | | 1558 | j checkromwork |
1556 | nop # - delay slot - | | 1559 | nop # - delay slot - |
1557 | 1: | | 1560 | 1: |
1558 | #else | | 1561 | #else |
1559 | beq k1, zero, outofworld # No. Failing beyond. . . | | 1562 | beq k1, zero, MIPSX(outofworld) # No. Failing beyond. . . |
1560 | nop # - delay slot - | | 1563 | nop # - delay slot - |
1561 | #endif | | 1564 | #endif |
1562 | PTR_L k1, _C_LABEL(Sysmap) | | 1565 | PTR_L k1, _C_LABEL(Sysmap) |
1563 | PTR_SRL k0, k0, 1 | | 1566 | PTR_SRL k0, k0, 1 |
1564 | PTR_SLL k0, k0, 3 # compute offset from index | | 1567 | PTR_SLL k0, k0, 3 # compute offset from index |
1565 | PTR_ADDU k1, k1, k0 | | 1568 | PTR_ADDU k1, k1, k0 |
1566 | INT_L k0, 0(k1) # get PTE entry | | 1569 | INT_L k0, 0(k1) # get PTE entry |
1567 | INT_L k1, 4(k1) # get odd PTE entry | | 1570 | INT_L k1, 4(k1) # get odd PTE entry |
1568 | _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit | | 1571 | _SLL k0, k0, WIRED_SHIFT # get rid of "wired" bit |
1569 | _SRL k0, k0, WIRED_SHIFT | | 1572 | _SRL k0, k0, WIRED_SHIFT |
1570 | _MTC0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry | | 1573 | _MTC0 k0, MIPS_COP_0_TLB_LO0 # load PTE entry |
1571 | COP0_SYNC | | 1574 | COP0_SYNC |
1572 | _SLL k1, k1, WIRED_SHIFT | | 1575 | _SLL k1, k1, WIRED_SHIFT |
| @@ -1574,27 +1577,27 @@ LEAF_NOPROFILE(MIPSX(TLBMissException)) | | | @@ -1574,27 +1577,27 @@ LEAF_NOPROFILE(MIPSX(TLBMissException)) |
1574 | _MTC0 k1, MIPS_COP_0_TLB_LO1 # load PTE entry | | 1577 | _MTC0 k1, MIPS_COP_0_TLB_LO1 # load PTE entry |
1575 | COP0_SYNC | | 1578 | COP0_SYNC |
1576 | nop | | 1579 | nop |
1577 | nop # required for QED5230 | | 1580 | nop # required for QED5230 |
1578 | tlbwr # write TLB | | 1581 | tlbwr # write TLB |
1579 | COP0_SYNC | | 1582 | COP0_SYNC |
1580 | nop | | 1583 | nop |
1581 | nop | | 1584 | nop |
1582 | nop | | 1585 | nop |
1583 | nop | | 1586 | nop |
1584 | nop | | 1587 | nop |
1585 | eret | | 1588 | eret |
1586 | | | 1589 | |
1587 | outofworld: | | 1590 | MIPSX(outofworld): |
1588 | /* eret to panic so shutdown can use K2. Try to ensure valid $sp. */ | | 1591 | /* eret to panic so shutdown can use K2. Try to ensure valid $sp. */ |
1589 | PTR_LA a0, _C_LABEL(panic) | | 1592 | PTR_LA a0, _C_LABEL(panic) |
1590 | _MFC0 a2, MIPS_COP_0_EXC_PC | | 1593 | _MFC0 a2, MIPS_COP_0_EXC_PC |
1591 | move a1, sp | | 1594 | move a1, sp |
1592 | PTR_SLL k0, k0, PGSHIFT | | 1595 | PTR_SLL k0, k0, PGSHIFT |
1593 | _MTC0 a0, MIPS_COP_0_EXC_PC # return to panic | | 1596 | _MTC0 a0, MIPS_COP_0_EXC_PC # return to panic |
1594 | COP0_SYNC | | 1597 | COP0_SYNC |
1595 | li k1, VM_MIN_KERNEL_ADDRESS | | 1598 | li k1, VM_MIN_KERNEL_ADDRESS |
1596 | PTR_ADDU a3, k0, k1 | | 1599 | PTR_ADDU a3, k0, k1 |
1597 | #if defined(DDB) | | 1600 | #if defined(DDB) |
1598 | bltz sp, 1f # for ddb try to keep frame | | 1601 | bltz sp, 1f # for ddb try to keep frame |
1599 | nop | | 1602 | nop |
1600 | #endif | | 1603 | #endif |
| @@ -1880,27 +1883,27 @@ LEAF_NOPROFILE(MIPSX(VCED)) | | | @@ -1880,27 +1883,27 @@ LEAF_NOPROFILE(MIPSX(VCED)) |
1880 | and k0, k1 | | 1883 | and k0, k1 |
1881 | cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) | | 1884 | cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) |
1882 | cache (CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0) | | 1885 | cache (CACHE_R4K_D | CACHEOP_R4K_HIT_INV), 0(k0) |
1883 | #ifdef DEBUG | | 1886 | #ifdef DEBUG |
1884 | _MFC0 k0, MIPS_COP_0_BAD_VADDR | | 1887 | _MFC0 k0, MIPS_COP_0_BAD_VADDR |
1885 | PTR_LA k1, VCED_vaddr | | 1888 | PTR_LA k1, VCED_vaddr |
1886 | PTR_S k0, 0(k1) | | 1889 | PTR_S k0, 0(k1) |
1887 | _MFC0 k0, MIPS_COP_0_EXC_PC | | 1890 | _MFC0 k0, MIPS_COP_0_EXC_PC |
1888 | PTR_LA k1, VCED_epc | | 1891 | PTR_LA k1, VCED_epc |
1889 | PTR_S k0, 0(k1) | | 1892 | PTR_S k0, 0(k1) |
1890 | PTR_LA k1, VCED_count # count number of exceptions | | 1893 | PTR_LA k1, VCED_count # count number of exceptions |
1891 | PTR_SRL k0, k0, 26 # position upper 4 bits of VA | | 1894 | PTR_SRL k0, k0, 26 # position upper 4 bits of VA |
1892 | and k0, k0, 0x3c # mask it off | | 1895 | and k0, k0, 0x3c # mask it off |
1893 | add k1, k0 # get address of count table | | 1896 | PTR_ADDU k1, k0 # get address of count table |
1894 | LONG_L k0, 0(k1) | | 1897 | LONG_L k0, 0(k1) |
1895 | LONG_ADDU k0, 1 | | 1898 | LONG_ADDU k0, 1 |
1896 | LONG_S k0, 0(k1) | | 1899 | LONG_S k0, 0(k1) |
1897 | #endif | | 1900 | #endif |
1898 | eret | | 1901 | eret |
1899 | .set at | | 1902 | .set at |
1900 | | | 1903 | |
1901 | #ifdef DEBUG | | 1904 | #ifdef DEBUG |
1902 | .data | | 1905 | .data |
1903 | .globl _C_LABEL(VCED_count) | | 1906 | .globl _C_LABEL(VCED_count) |
1904 | _C_LABEL(VCED_count): | | 1907 | _C_LABEL(VCED_count): |
1905 | LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | | 1908 | LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
1906 | .globl _C_LABEL(VCED_epc) | | 1909 | .globl _C_LABEL(VCED_epc) |
| @@ -1915,29 +1918,29 @@ END(MIPSX(VCED)) | | | @@ -1915,29 +1918,29 @@ END(MIPSX(VCED)) |
1915 | | | 1918 | |
1916 | LEAF_NOPROFILE(MIPSX(VCEI)) | | 1919 | LEAF_NOPROFILE(MIPSX(VCEI)) |
1917 | .set noat | | 1920 | .set noat |
1918 | _MFC0 k0, MIPS_COP_0_BAD_VADDR # fault addr. | | 1921 | _MFC0 k0, MIPS_COP_0_BAD_VADDR # fault addr. |
1919 | cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) | | 1922 | cache (CACHE_R4K_SD | CACHEOP_R4K_HIT_WB_INV), 0(k0) |
1920 | cache (CACHE_R4K_I | CACHEOP_R4K_HIT_INV), 0(k0) | | 1923 | cache (CACHE_R4K_I | CACHEOP_R4K_HIT_INV), 0(k0) |
1921 | #ifdef DEBUG | | 1924 | #ifdef DEBUG |
1922 | _MFC0 k0, MIPS_COP_0_BAD_VADDR | | 1925 | _MFC0 k0, MIPS_COP_0_BAD_VADDR |
1923 | PTR_LA k1, VCEI_vaddr | | 1926 | PTR_LA k1, VCEI_vaddr |
1924 | PTR_S k0, 0(k1) | | 1927 | PTR_S k0, 0(k1) |
1925 | PTR_LA k1, VCEI_count # count number of exceptions | | 1928 | PTR_LA k1, VCEI_count # count number of exceptions |
1926 | PTR_SRL k0, k0, 26 # position upper 4 bits of VA | | 1929 | PTR_SRL k0, k0, 26 # position upper 4 bits of VA |
1927 | and k0, k0, 0x3c # mask it off | | 1930 | and k0, k0, 0x3c # mask it off |
1928 | add k1, k0 # get address of count table | | 1931 | PTR_ADDU k1, k0 # get address of count table |
1929 | LONG_L k0, 0(k1) | | 1932 | LONG_L k0, 0(k1) |
1930 | addu k0, 1 | | 1933 | PTR_ADDU k0, 1 |
1931 | LONG_S k0, 0(k1) | | 1934 | LONG_S k0, 0(k1) |
1932 | #endif | | 1935 | #endif |
1933 | eret | | 1936 | eret |
1934 | .set at | | 1937 | .set at |
1935 | | | 1938 | |
1936 | #ifdef DEBUG | | 1939 | #ifdef DEBUG |
1937 | .data | | 1940 | .data |
1938 | .globl _C_LABEL(VCEI_count) | | 1941 | .globl _C_LABEL(VCEI_count) |
1939 | _C_LABEL(VCEI_count): | | 1942 | _C_LABEL(VCEI_count): |
1940 | LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | | 1943 | LONG_WORD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
1941 | .globl _C_LABEL(VCEI_vaddr) | | 1944 | .globl _C_LABEL(VCEI_vaddr) |
1942 | _C_LABEL(VCEI_vaddr): | | 1945 | _C_LABEL(VCEI_vaddr): |
1943 | PTR_WORD 0 | | 1946 | PTR_WORD 0 |
| @@ -2149,28 +2152,28 @@ LEAF_NOPROFILE(MIPSX(TBIS)) | | | @@ -2149,28 +2152,28 @@ LEAF_NOPROFILE(MIPSX(TBIS)) |
2149 | _MTC0 a0, MIPS_COP_0_TLB_HI # look for the vaddr & ASID | | 2152 | _MTC0 a0, MIPS_COP_0_TLB_HI # look for the vaddr & ASID |
2150 | COP0_SYNC | | 2153 | COP0_SYNC |
2151 | nop | | 2154 | nop |
2152 | nop | | 2155 | nop |
2153 | tlbp # probe the entry in question | | 2156 | tlbp # probe the entry in question |
2154 | COP0_SYNC | | 2157 | COP0_SYNC |
2155 | nop | | 2158 | nop |
2156 | nop | | 2159 | nop |
2157 | mfc0 v0, MIPS_COP_0_TLB_INDEX # see what we got | | 2160 | mfc0 v0, MIPS_COP_0_TLB_INDEX # see what we got |
2158 | #nop # -slip- | | 2161 | #nop # -slip- |
2159 | #nop # -slip- | | 2162 | #nop # -slip- |
2160 | bltz v0, 1f # index < 0 then skip | | 2163 | bltz v0, 1f # index < 0 then skip |
2161 | li t1, MIPS_KSEG0_START # invalid address | | 2164 | li t1, MIPS_KSEG0_START # invalid address |
2162 | sll v0, v0, PGSHIFT + 1 # PAGE_SHIFT + 1 | | 2165 | PTR_SLL v0, v0, PGSHIFT + 1 # PAGE_SHIFT + 1 |
2163 | addu t1, t1, v0 | | 2166 | PTR_ADDU t1, t1, v0 |
2164 | _MTC0 t1, MIPS_COP_0_TLB_HI # make entryHi invalid | | 2167 | _MTC0 t1, MIPS_COP_0_TLB_HI # make entryHi invalid |
2165 | COP0_SYNC | | 2168 | COP0_SYNC |
2166 | _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 | | 2169 | _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 |
2167 | COP0_SYNC | | 2170 | COP0_SYNC |
2168 | _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 | | 2171 | _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 |
2169 | COP0_SYNC | | 2172 | COP0_SYNC |
2170 | #if 1 | | 2173 | #if 1 |
2171 | nop | | 2174 | nop |
2172 | #else | | 2175 | #else |
2173 | mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask | | 2176 | mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out pageMask |
2174 | #endif | | 2177 | #endif |
2175 | COP0_SYNC | | 2178 | COP0_SYNC |
2176 | nop | | 2179 | nop |
| @@ -2215,27 +2218,27 @@ LEAF_NOPROFILE(MIPSX(TBIAP)) | | | @@ -2215,27 +2218,27 @@ LEAF_NOPROFILE(MIPSX(TBIAP)) |
2215 | sll ta0, t1, PGSHIFT + 1 # PAGE_SHIFT + 1 | | 2218 | sll ta0, t1, PGSHIFT + 1 # PAGE_SHIFT + 1 |
2216 | nop | | 2219 | nop |
2217 | /* XXX simonb: lose this nop for mips32/64? */ | | 2220 | /* XXX simonb: lose this nop for mips32/64? */ |
2218 | nop | | 2221 | nop |
2219 | tlbr # obtain an entry | | 2222 | tlbr # obtain an entry |
2220 | COP0_SYNC | | 2223 | COP0_SYNC |
2221 | /* XXX simonb: lose these nops for mips32/64? */ | | 2224 | /* XXX simonb: lose these nops for mips32/64? */ |
2222 | nop | | 2225 | nop |
2223 | nop | | 2226 | nop |
2224 | nop | | 2227 | nop |
2225 | _MFC0 a0, MIPS_COP_0_TLB_LO1 | | 2228 | _MFC0 a0, MIPS_COP_0_TLB_LO1 |
2226 | and a0, a0, MIPS3_PG_G # check to see it has G bit | | 2229 | and a0, a0, MIPS3_PG_G # check to see it has G bit |
2227 | bnez a0, 2f | | 2230 | bnez a0, 2f |
2228 | addu ta0, ta0, v0 | | 2231 | PTR_ADDU ta0, ta0, v0 |
2229 | | | 2232 | |
2230 | _MTC0 ta0, MIPS_COP_0_TLB_HI # make entryHi invalid | | 2233 | _MTC0 ta0, MIPS_COP_0_TLB_HI # make entryHi invalid |
2231 | COP0_SYNC | | 2234 | COP0_SYNC |
2232 | _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 | | 2235 | _MTC0 zero, MIPS_COP_0_TLB_LO0 # zero out entryLo0 |
2233 | COP0_SYNC | | 2236 | COP0_SYNC |
2234 | _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 | | 2237 | _MTC0 zero, MIPS_COP_0_TLB_LO1 # zero out entryLo1 |
2235 | COP0_SYNC | | 2238 | COP0_SYNC |
2236 | mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out mask entry | | 2239 | mtc0 zero, MIPS_COP_0_TLB_PG_MASK # zero out mask entry |
2237 | COP0_SYNC | | 2240 | COP0_SYNC |
2238 | /* XXX simonb: lose these nops for mips32/64? */ | | 2241 | /* XXX simonb: lose these nops for mips32/64? */ |
2239 | nop | | 2242 | nop |
2240 | nop | | 2243 | nop |
2241 | tlbwi # invalidate the TLB entry | | 2244 | tlbwi # invalidate the TLB entry |