445 |
445 |
|
446 |
446 |
if (rw == 1) {
|
447 |
447 |
sfsr |= SFSR_WRITE_BIT;
|
|
448 |
} else if (rw == 4) {
|
|
449 |
sfsr |= SFSR_NF_BIT;
|
448 |
450 |
}
|
449 |
451 |
|
450 |
452 |
for (i = 0; i < 64; i++) {
|
451 |
453 |
// ctx match, vaddr match, valid?
|
452 |
454 |
if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
|
|
455 |
int do_fault = 0;
|
453 |
456 |
|
454 |
457 |
// access ok?
|
|
458 |
/* multiple bits in SFSR.FT may be set on TT_DFAULT */
|
455 |
459 |
if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
|
|
460 |
do_fault = 1;
|
456 |
461 |
sfsr |= SFSR_FT_PRIV_BIT; /* privilege violation */
|
457 |
|
env->exception_index = TT_DFAULT;
|
458 |
462 |
|
459 |
463 |
DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
|
460 |
464 |
" mmu_idx=%d tl=%d\n",
|
461 |
465 |
address, context, mmu_idx, env->tl);
|
|
466 |
}
|
|
467 |
if (rw == 4) {
|
|
468 |
if (TTE_IS_SIDEEFFECT(env->dtlb[i].tte)) {
|
|
469 |
do_fault = 1;
|
|
470 |
sfsr |= SFSR_FT_NF_E_BIT;
|
|
471 |
}
|
|
472 |
} else {
|
|
473 |
if (TTE_IS_NFO(env->dtlb[i].tte)) {
|
|
474 |
do_fault = 1;
|
|
475 |
sfsr |= SFSR_FT_NFO_BIT;
|
|
476 |
}
|
|
477 |
}
|
|
478 |
|
|
479 |
if (do_fault) {
|
|
480 |
/* faults above are reported with TT_DFAULT. */
|
|
481 |
env->exception_index = TT_DFAULT;
|
462 |
482 |
} else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
|
|
483 |
do_fault = 1;
|
463 |
484 |
env->exception_index = TT_DPROT;
|
464 |
485 |
|
465 |
486 |
DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
|
466 |
487 |
" mmu_idx=%d tl=%d\n",
|
467 |
488 |
address, context, mmu_idx, env->tl);
|
468 |
|
} else {
|
|
489 |
}
|
|
490 |
|
|
491 |
if (!do_fault) {
|
469 |
492 |
*prot = PAGE_READ;
|
470 |
493 |
if (TTE_IS_W_OK(env->dtlb[i].tte)) {
|
471 |
494 |
*prot |= PAGE_WRITE;
|
... | ... | |
752 |
775 |
{
|
753 |
776 |
target_phys_addr_t phys_addr;
|
754 |
777 |
|
755 |
|
if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
|
|
778 |
if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 4, mmu_idx) != 0) {
|
756 |
779 |
return -1;
|
757 |
780 |
}
|
758 |
781 |
return phys_addr;
|