Revision 628b61a0

b/target-sh4/helper.c
386 386
	n = find_utlb_entry(env, address, use_asid);
387 387
	if (n >= 0) {
388 388
	    matching = &env->utlb[n];
389
	    switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
390
	    case 0:		/* 000 */
391
	    case 2:		/* 010 */
392
		n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
393
		    MMU_DTLB_VIOLATION_READ;
394
		break;
395
	    case 1:		/* 001 */
396
	    case 4:		/* 100 */
397
	    case 5:		/* 101 */
398
		if (rw == 1)
399
		    n = MMU_DTLB_VIOLATION_WRITE;
400
		else
401
		    *prot = PAGE_READ;
402
		break;
403
	    case 3:		/* 011 */
404
	    case 6:		/* 110 */
405
	    case 7:		/* 111 */
406
		*prot = (rw == 1)? PAGE_WRITE : PAGE_READ;
407
		break;
408
	    }
389
            if (!(env->sr & SR_MD) && !(matching->pr & 2)) {
390
                n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
391
                    MMU_DTLB_VIOLATION_READ;
392
            } else if ((rw == 1) && !(matching->pr & 1)) {
393
                n = MMU_DTLB_VIOLATION_WRITE;
394
            } else if ((rw == 1) & !matching->d) {
395
                n = MMU_DTLB_INITIAL_WRITE;
396
            } else {
397
                *prot = PAGE_READ;
398
                if ((matching->pr & 1) && matching->d) {
399
                    *prot |= PAGE_WRITE;
400
                }
401
            }
409 402
	} else if (n == MMU_DTLB_MISS) {
410 403
	    n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
411 404
		MMU_DTLB_MISS_READ;
412 405
	}
413 406
    }
414 407
    if (n >= 0) {
408
	n = MMU_OK;
415 409
	*physical = ((matching->ppn << 10) & ~(matching->size - 1)) |
416 410
	    (address & (matching->size - 1));
417
	if ((rw == 1) & !matching->d)
418
	    n = MMU_DTLB_INITIAL_WRITE;
419
	else
420
	    n = MMU_OK;
421 411
    }
422 412
    return n;
423 413
}

Also available in: Unified diff