Revision bb218042 target-ppc/mmu-hash64.c
b/target-ppc/mmu-hash64.c | ||
---|---|---|
454 | 454 |
return 0; |
455 | 455 |
} |
456 | 456 |
|
457 |
pr = msr_pr; |
|
458 |
|
|
459 |
LOG_MMU("Check SLBs\n"); |
|
457 |
/* 2. Translation is on, so look up the SLB */ |
|
460 | 458 |
slb = slb_lookup(env, eaddr); |
459 |
|
|
461 | 460 |
if (!slb) { |
462 | 461 |
return -5; |
463 | 462 |
} |
464 | 463 |
|
464 |
/* 3. Check for segment level no-execute violation */ |
|
465 |
if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) { |
|
466 |
return -3; |
|
467 |
} |
|
468 |
|
|
469 |
pr = msr_pr; |
|
470 |
|
|
465 | 471 |
if (slb->vsid & SLB_VSID_B) { |
466 | 472 |
vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T; |
467 | 473 |
segment_bits = 40; |
... | ... | |
490 | 496 |
ctx->key, !!(slb->vsid & SLB_VSID_N), vsid); |
491 | 497 |
ret = -1; |
492 | 498 |
|
493 |
/* Check if instruction fetch is allowed, if needed */ |
|
494 |
if (rwx != 2 || !(slb->vsid & SLB_VSID_N)) { |
|
495 |
/* Page address translation */ |
|
496 |
LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx |
|
497 |
" hash " TARGET_FMT_plx "\n", |
|
498 |
env->htab_base, env->htab_mask, hash); |
|
499 |
ctx->hash[0] = hash; |
|
500 |
ctx->hash[1] = ~hash; |
|
501 |
|
|
502 |
/* Initialize real address with an invalid value */ |
|
503 |
ctx->raddr = (hwaddr)-1ULL; |
|
504 |
LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx |
|
505 |
" vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx |
|
506 |
" hash=" TARGET_FMT_plx "\n", |
|
507 |
env->htab_base, env->htab_mask, vsid, ctx->ptem, |
|
508 |
ctx->hash[0]); |
|
509 |
/* Primary table lookup */ |
|
510 |
ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits); |
|
511 |
if (ret < 0) { |
|
512 |
/* Secondary table lookup */ |
|
513 |
LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx |
|
514 |
" vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx |
|
515 |
" hash=" TARGET_FMT_plx "\n", env->htab_base, |
|
516 |
env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); |
|
517 |
ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits); |
|
518 |
if (ret2 != -1) { |
|
519 |
ret = ret2; |
|
520 |
} |
|
499 |
/* Page address translation */ |
|
500 |
LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx |
|
501 |
" hash " TARGET_FMT_plx "\n", |
|
502 |
env->htab_base, env->htab_mask, hash); |
|
503 |
ctx->hash[0] = hash; |
|
504 |
ctx->hash[1] = ~hash; |
|
505 |
|
|
506 |
/* Initialize real address with an invalid value */ |
|
507 |
ctx->raddr = (hwaddr)-1ULL; |
|
508 |
LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx |
|
509 |
" vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx |
|
510 |
" hash=" TARGET_FMT_plx "\n", |
|
511 |
env->htab_base, env->htab_mask, vsid, ctx->ptem, |
|
512 |
ctx->hash[0]); |
|
513 |
/* Primary table lookup */ |
|
514 |
ret = find_pte64(env, ctx, eaddr, 0, rwx, target_page_bits); |
|
515 |
if (ret < 0) { |
|
516 |
/* Secondary table lookup */ |
|
517 |
LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx |
|
518 |
" vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx |
|
519 |
" hash=" TARGET_FMT_plx "\n", env->htab_base, |
|
520 |
env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); |
|
521 |
ret2 = find_pte64(env, ctx, eaddr, 1, rwx, target_page_bits); |
|
522 |
if (ret2 != -1) { |
|
523 |
ret = ret2; |
|
521 | 524 |
} |
522 |
} else { |
|
523 |
LOG_MMU("No access allowed\n"); |
|
524 |
ret = -3; |
|
525 | 525 |
} |
526 | 526 |
|
527 | 527 |
return ret; |
Also available in: Unified diff