76 |
76 |
target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
|
77 |
77 |
target_ulong tag = address & ~mask;
|
78 |
78 |
target_ulong VPN = tlb->VPN & ~mask;
|
|
79 |
#ifdef TARGET_MIPS64
|
|
80 |
tag &= 0xC00000FFFFFFFFFFULL;
|
|
81 |
#endif
|
79 |
82 |
|
80 |
83 |
/* Check ASID, virtual page number & size */
|
81 |
84 |
if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag) {
|
... | ... | |
295 |
298 |
}
|
296 |
299 |
/* Raise exception */
|
297 |
300 |
env->CP0_BadVAddr = address;
|
298 |
|
env->CP0_Context = (env->CP0_Context & 0xff800000) |
|
|
301 |
env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
|
299 |
302 |
((address >> 9) & 0x007ffff0);
|
300 |
303 |
env->CP0_EntryHi =
|
301 |
304 |
(env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
|
|
305 |
#ifdef TARGET_MIPS64
|
|
306 |
env->CP0_EntryHi &= 0xc00000ffffffffffULL;
|
|
307 |
env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
|
|
308 |
((address >> 31) & 0x0000000180000000ULL) |
|
|
309 |
((address >> 9) & 0x000000007ffffff0ULL);
|
|
310 |
#endif
|
302 |
311 |
env->exception_index = exception;
|
303 |
312 |
env->error_code = error_code;
|
304 |
313 |
ret = 1;
|
... | ... | |
411 |
420 |
goto set_EPC;
|
412 |
421 |
case EXCP_TLBL:
|
413 |
422 |
cause = 2;
|
414 |
|
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
|
415 |
|
offset = 0x000;
|
|
423 |
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
|
|
424 |
#ifdef TARGET_MIPS64
|
|
425 |
int R = env->CP0_BadVAddr >> 62;
|
|
426 |
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
|
|
427 |
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
|
|
428 |
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
|
|
429 |
|
|
430 |
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
|
|
431 |
offset = 0x080;
|
|
432 |
else
|
|
433 |
#endif
|
|
434 |
offset = 0x000;
|
|
435 |
}
|
416 |
436 |
goto set_EPC;
|
417 |
437 |
case EXCP_IBE:
|
418 |
438 |
cause = 6;
|
... | ... | |
448 |
468 |
goto set_EPC;
|
449 |
469 |
case EXCP_TLBS:
|
450 |
470 |
cause = 3;
|
451 |
|
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
|
452 |
|
offset = 0x000;
|
|
471 |
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
|
|
472 |
#ifdef TARGET_MIPS64
|
|
473 |
int R = env->CP0_BadVAddr >> 62;
|
|
474 |
int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
|
|
475 |
int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
|
|
476 |
int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
|
|
477 |
|
|
478 |
if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
|
|
479 |
offset = 0x080;
|
|
480 |
else
|
|
481 |
#endif
|
|
482 |
offset = 0x000;
|
|
483 |
}
|
453 |
484 |
set_EPC:
|
454 |
485 |
if (!(env->CP0_Status & (1 << CP0St_EXL))) {
|
455 |
486 |
if (env->hflags & MIPS_HFLAG_BMASK) {
|
... | ... | |
520 |
551 |
mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
|
521 |
552 |
if (tlb->V0) {
|
522 |
553 |
addr = tlb->VPN & ~mask;
|
|
554 |
#ifdef TARGET_MIPS64
|
|
555 |
if (addr >= 0xC00000FF80000000ULL) {
|
|
556 |
addr |= 0x3FFFFF0000000000ULL;
|
|
557 |
}
|
|
558 |
#endif
|
523 |
559 |
end = addr | (mask >> 1);
|
524 |
560 |
while (addr < end) {
|
525 |
561 |
tlb_flush_page (env, addr);
|
... | ... | |
528 |
564 |
}
|
529 |
565 |
if (tlb->V1) {
|
530 |
566 |
addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
|
|
567 |
#ifdef TARGET_MIPS64
|
|
568 |
if (addr >= 0xC00000FF80000000ULL) {
|
|
569 |
addr |= 0x3FFFFF0000000000ULL;
|
|
570 |
}
|
|
571 |
#endif
|
531 |
572 |
end = addr | mask;
|
532 |
573 |
while (addr < end) {
|
533 |
574 |
tlb_flush_page (env, addr);
|