mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 20:19:44 +00:00
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:
parent
57d0a39d98
commit
b344074642
@ -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)
|
||||
{
|
||||
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;
|
||||
hwaddr pte_offset;
|
||||
ppc_hash_pte32_t pte;
|
||||
uint32_t new_pte1;
|
||||
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
|
||||
|
||||
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 */
|
||||
|
||||
if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) {
|
||||
ppc_hash32_store_hpte1(env, pte_offset, pte.pte1);
|
||||
new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
|
||||
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 */
|
||||
|
@ -280,31 +280,6 @@ static int ppc_hash64_pte_prot(CPUPPCState *env,
|
||||
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,
|
||||
bool secondary, target_ulong ptem,
|
||||
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;
|
||||
hwaddr pte_offset;
|
||||
ppc_hash_pte64_t pte;
|
||||
uint64_t new_pte1;
|
||||
int target_page_bits;
|
||||
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 */
|
||||
|
||||
if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) {
|
||||
ppc_hash64_store_hpte1(env, pte_offset, pte.pte1);
|
||||
new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user