Revision 100ce988 target-mips/helper.c
b/target-mips/helper.c | ||
---|---|---|
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); |
Also available in: Unified diff