mmu-hash*: Clean up PTE flags update

Currently the ppc_hash{32,64}_pte_update_flags() helper functions update a
PTE's referenced and changed bits as necessary to reflect the access.  It
is somewhat long winded, though.  This patch open codes them in their
(single) callers, in a simpler way.

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:42 +00:00 committed by Alexander Graf
parent 57d0a39d98
commit b344074642
2 changed files with 24 additions and 54 deletions

View File

@ -274,31 +274,6 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
} }
} }
static int ppc_hash32_pte_update_flags(struct mmu_ctx_hash32 *ctx, uint32_t *pte1p,
int ret, int rwx)
{
int store = 0;
/* Update page flags */
if (!(*pte1p & HPTE32_R_R)) {
/* Update accessed flag */
*pte1p |= HPTE32_R_R;
store = 1;
}
if (!(*pte1p & HPTE32_R_C)) {
if (rwx == 1 && ret == 0) {
/* Update changed flag */
*pte1p |= HPTE32_R_C;
store = 1;
} else {
/* Force page fault for first write access */
ctx->prot &= ~PAGE_WRITE;
}
}
return store;
}
hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash) hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
{ {
return (hash * HASH_PTEG_SIZE_32) & env->htab_mask; return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
@ -374,6 +349,7 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
target_ulong sr; target_ulong sr;
hwaddr pte_offset; hwaddr pte_offset;
ppc_hash_pte32_t pte; ppc_hash_pte32_t pte;
uint32_t new_pte1;
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
assert((rwx == 0) || (rwx == 1) || (rwx == 2)); assert((rwx == 0) || (rwx == 1) || (rwx == 2));
@ -432,8 +408,17 @@ static int ppc_hash32_translate(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,
/* 8. Update PTE referenced and changed bits if necessary */ /* 8. Update PTE referenced and changed bits if necessary */
if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) { new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
ppc_hash32_store_hpte1(env, pte_offset, pte.pte1); if (rwx == 1) {
new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */
} else {
/* Treat the page as read-only for now, so that a later write
* will pass through this function again to set the C bit */
ctx->prot &= ~PAGE_WRITE;
}
if (new_pte1 != pte.pte1) {
ppc_hash32_store_hpte1(env, pte_offset, new_pte1);
} }
/* Keep the matching PTE informations */ /* Keep the matching PTE informations */

View File

@ -280,31 +280,6 @@ static int ppc_hash64_pte_prot(CPUPPCState *env,
return prot; return prot;
} }
static int ppc_hash64_pte_update_flags(struct mmu_ctx_hash64 *ctx,
uint64_t *pte1p, int ret, int rw)
{
int store = 0;
/* Update page flags */
if (!(*pte1p & HPTE64_R_R)) {
/* Update accessed flag */
*pte1p |= HPTE64_R_R;
store = 1;
}
if (!(*pte1p & HPTE64_R_C)) {
if (rw == 1 && ret == 0) {
/* Update changed flag */
*pte1p |= HPTE64_R_C;
store = 1;
} else {
/* Force page fault for first write access */
ctx->prot &= ~PAGE_WRITE;
}
}
return store;
}
static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off, static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
bool secondary, target_ulong ptem, bool secondary, target_ulong ptem,
ppc_hash_pte64_t *pte) ppc_hash_pte64_t *pte)
@ -393,6 +368,7 @@ static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
ppc_slb_t *slb; ppc_slb_t *slb;
hwaddr pte_offset; hwaddr pte_offset;
ppc_hash_pte64_t pte; ppc_hash_pte64_t pte;
uint64_t new_pte1;
int target_page_bits; int target_page_bits;
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC}; const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
@ -440,8 +416,17 @@ static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx,
/* 6. Update PTE referenced and changed bits if necessary */ /* 6. Update PTE referenced and changed bits if necessary */
if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) { new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */
ppc_hash64_store_hpte1(env, pte_offset, pte.pte1); if (rwx == 1) {
new_pte1 |= HPTE64_R_C; /* set changed (dirty) bit */
} else {
/* Treat the page as read-only for now, so that a later write
* will pass through this function again to set the C bit */
ctx->prot &= ~PAGE_WRITE;
}
if (new_pte1 != pte.pte1) {
ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
} }
/* Keep the matching PTE informations */ /* Keep the matching PTE informations */