mmu-hash32: Split BAT size logic from permissions logic

hash32_bat_size_prot() and its 601 variant, as the name suggests, returns
both a BAT's size - needed to search for a matching BAT - and its
permissions, only relevant once a matching BAT has been located.

There's no particular advantage to combining these, so we split these roles
into seperate functions for clarity.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
David Gibson 2013-03-12 00:31:34 +00:00 committed by Alexander Graf
parent 9986ed1ed0
commit e1d4951593
1 changed files with 40 additions and 31 deletions

View File

@ -113,57 +113,64 @@ static int ppc_hash32_check_prot(int prot, int rwx)
return ret; return ret;
} }
/* Perform BAT hit & translation */ static void hash32_bat_size(CPUPPCState *env, target_ulong *blp, int *validp,
static void hash32_bat_size_prot(CPUPPCState *env, target_ulong *blp, target_ulong batu, target_ulong batl)
int *validp, int *protp,
target_ulong batu, target_ulong batl)
{ {
target_ulong bl; target_ulong bl;
int pp, valid, prot; int valid;
bl = (batu & BATU32_BL) << 15; bl = (batu & BATU32_BL) << 15;
valid = 0; valid = 0;
prot = 0;
if (((msr_pr == 0) && (batu & BATU32_VS)) || if (((msr_pr == 0) && (batu & BATU32_VS)) ||
((msr_pr != 0) && (batu & BATU32_VP))) { ((msr_pr != 0) && (batu & BATU32_VP))) {
valid = 1; valid = 1;
pp = batl & BATL32_PP;
if (pp != 0) {
prot = PAGE_READ | PAGE_EXEC;
if (pp == 0x2) {
prot |= PAGE_WRITE;
}
}
} }
*blp = bl; *blp = bl;
*validp = valid; *validp = valid;
*protp = prot;
} }
static void hash32_bat_601_size_prot(CPUPPCState *env, target_ulong *blp, static int hash32_bat_prot(CPUPPCState *env,
int *validp, int *protp, target_ulong batu, target_ulong batl)
target_ulong batu, target_ulong batl) {
int pp, prot;
prot = 0;
pp = batl & BATL32_PP;
if (pp != 0) {
prot = PAGE_READ | PAGE_EXEC;
if (pp == 0x2) {
prot |= PAGE_WRITE;
}
}
return prot;
}
static void hash32_bat_601_size(CPUPPCState *env, target_ulong *blp, int *validp,
target_ulong batu, target_ulong batl)
{ {
target_ulong bl; target_ulong bl;
int key, pp, valid, prot; int valid;
bl = (batl & BATL32_601_BL) << 17; bl = (batl & BATL32_601_BL) << 17;
LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n", LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
(uint8_t)(batl & BATL32_601_BL), bl, ~bl); (uint8_t)(batl & BATL32_601_BL), bl, ~bl);
prot = 0;
valid = !!(batl & BATL32_601_V); valid = !!(batl & BATL32_601_V);
if (valid) {
pp = batu & BATU32_601_PP;
if (msr_pr == 0) {
key = !!(batu & BATU32_601_KS);
} else {
key = !!(batu & BATU32_601_KP);
}
prot = ppc_hash32_pp_check(key, pp, 0);
}
*blp = bl; *blp = bl;
*validp = valid; *validp = valid;
*protp = prot; }
static int hash32_bat_601_prot(CPUPPCState *env,
target_ulong batu, target_ulong batl)
{
int key, pp;
pp = batu & BATU32_601_PP;
if (msr_pr == 0) {
key = !!(batu & BATU32_601_KS);
} else {
key = !!(batu & BATU32_601_KP);
}
return ppc_hash32_pp_check(key, pp, 0);
} }
static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
@ -190,9 +197,11 @@ static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
BEPIu = batu & BATU32_BEPIU; BEPIu = batu & BATU32_BEPIU;
BEPIl = batu & BATU32_BEPIL; BEPIl = batu & BATU32_BEPIL;
if (unlikely(env->mmu_model == POWERPC_MMU_601)) { if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
hash32_bat_601_size_prot(env, &bl, &valid, &prot, batu, batl); hash32_bat_601_size(env, &bl, &valid, batu, batl);
prot = hash32_bat_601_prot(env, batu, batl);
} else { } else {
hash32_bat_size_prot(env, &bl, &valid, &prot, batu, batl); hash32_bat_size(env, &bl, &valid, 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__,