mmu-hash32: Cleanup BAT lookup
This patch makes a general cleanup of the ppc_hash32_get_bat() function, renaming it to ppc_hash32_bat_lookup(). In particular, the new function only looks for a matching BAT, with the permissions check from the old function moved to the caller. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
6fc76aa9ad
commit
145e52f318
@ -164,15 +164,14 @@ static int hash32_bat_601_prot(CPUPPCState *env,
|
|||||||
return ppc_hash32_pp_check(key, pp, 0);
|
return ppc_hash32_pp_check(key, pp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
|
static hwaddr ppc_hash32_bat_lookup(CPUPPCState *env, target_ulong ea, int rwx,
|
||||||
target_ulong virtual, int rwx)
|
int *prot)
|
||||||
{
|
{
|
||||||
target_ulong *BATlt, *BATut;
|
target_ulong *BATlt, *BATut;
|
||||||
int i, prot;
|
int i;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
|
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
|
||||||
rwx == 2 ? 'I' : 'D', virtual);
|
rwx == 2 ? 'I' : 'D', ea);
|
||||||
if (rwx == 2) {
|
if (rwx == 2) {
|
||||||
BATlt = env->IBAT[1];
|
BATlt = env->IBAT[1];
|
||||||
BATut = env->IBAT[0];
|
BATut = env->IBAT[0];
|
||||||
@ -187,35 +186,30 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
|
|||||||
|
|
||||||
if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
|
if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
|
||||||
mask = hash32_bat_601_size(env, batu, batl);
|
mask = hash32_bat_601_size(env, batu, batl);
|
||||||
prot = hash32_bat_601_prot(env, batu, batl);
|
|
||||||
} else {
|
} else {
|
||||||
mask = hash32_bat_size(env, batu, batl);
|
mask = hash32_bat_size(env, batu, batl);
|
||||||
prot = hash32_bat_prot(env, batu, batl);
|
|
||||||
}
|
}
|
||||||
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
||||||
" BATl " TARGET_FMT_lx "\n", __func__,
|
" BATl " TARGET_FMT_lx "\n", __func__,
|
||||||
type == ACCESS_CODE ? 'I' : 'D', i, virtual, batu, batl);
|
type == ACCESS_CODE ? 'I' : 'D', i, ea, batu, batl);
|
||||||
|
|
||||||
if (mask && ((virtual & mask) == (batu & BATU32_BEPI))) {
|
if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
|
||||||
/* BAT matches */
|
hwaddr raddr = (batl & mask) | (ea & ~mask);
|
||||||
/* Get physical address */
|
|
||||||
ctx->raddr = (batl & mask) | (virtual & ~mask);
|
if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
|
||||||
ctx->raddr &= TARGET_PAGE_MASK;
|
*prot = hash32_bat_601_prot(env, batu, batl);
|
||||||
/* Compute access rights */
|
} else {
|
||||||
ctx->prot = prot;
|
*prot = hash32_bat_prot(env, batu, batl);
|
||||||
ret = ppc_hash32_check_prot(ctx->prot, rwx);
|
|
||||||
if (ret == 0) {
|
|
||||||
LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
|
|
||||||
i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
|
|
||||||
ctx->prot & PAGE_WRITE ? 'W' : '-');
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
return raddr & TARGET_PAGE_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
|
||||||
|
/* No hit */
|
||||||
#if defined(DEBUG_BATS)
|
#if defined(DEBUG_BATS)
|
||||||
if (qemu_log_enabled()) {
|
if (qemu_log_enabled()) {
|
||||||
LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
|
LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", ea);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
BATu = &BATut[i];
|
BATu = &BATut[i];
|
||||||
BATl = &BATlt[i];
|
BATl = &BATlt[i];
|
||||||
@ -225,14 +219,13 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
|
|||||||
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
||||||
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
|
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
|
||||||
TARGET_FMT_lx " " TARGET_FMT_lx "\n",
|
TARGET_FMT_lx " " TARGET_FMT_lx "\n",
|
||||||
__func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
|
__func__, type == ACCESS_CODE ? 'I' : 'D', i, ea,
|
||||||
*BATu, *BATl, BEPIu, BEPIl, bl);
|
*BATu, *BATl, BEPIu, BEPIl, bl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
/* No hit */
|
return -1;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
|
static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
|
||||||
@ -405,11 +398,14 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
|
|||||||
|
|
||||||
/* 2. Check Block Address Translation entries (BATs) */
|
/* 2. Check Block Address Translation entries (BATs) */
|
||||||
if (env->nb_BATs != 0) {
|
if (env->nb_BATs != 0) {
|
||||||
ret = ppc_hash32_get_bat(env, ctx, eaddr, rwx);
|
ctx->raddr = ppc_hash32_bat_lookup(env, eaddr, rwx, &ctx->prot);
|
||||||
|
if (ctx->raddr != -1) {
|
||||||
|
ret = ppc_hash32_check_prot(ctx->prot, rwx);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 3. Look up the Segment Register */
|
/* 3. Look up the Segment Register */
|
||||||
sr = env->sr[eaddr >> 28];
|
sr = env->sr[eaddr >> 28];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user