Revision b3440746 target-ppc/mmu-hash32.c

b/target-ppc/mmu-hash32.c
274 274
    }
275 275
}
276 276

  
277
static int ppc_hash32_pte_update_flags(struct mmu_ctx_hash32 *ctx, uint32_t *pte1p,
278
                                       int ret, int rwx)
279
{
280
    int store = 0;
281

  
282
    /* Update page flags */
283
    if (!(*pte1p & HPTE32_R_R)) {
284
        /* Update accessed flag */
285
        *pte1p |= HPTE32_R_R;
286
        store = 1;
287
    }
288
    if (!(*pte1p & HPTE32_R_C)) {
289
        if (rwx == 1 && ret == 0) {
290
            /* Update changed flag */
291
            *pte1p |= HPTE32_R_C;
292
            store = 1;
293
        } else {
294
            /* Force page fault for first write access */
295
            ctx->prot &= ~PAGE_WRITE;
296
        }
297
    }
298

  
299
    return store;
300
}
301

  
302 277
hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
303 278
{
304 279
    return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
......
374 349
    target_ulong sr;
375 350
    hwaddr pte_offset;
376 351
    ppc_hash_pte32_t pte;
352
    uint32_t new_pte1;
377 353
    const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
378 354

  
379 355
    assert((rwx == 0) || (rwx == 1) || (rwx == 2));
......
432 408

  
433 409
    /* 8. Update PTE referenced and changed bits if necessary */
434 410

  
435
    if (ppc_hash32_pte_update_flags(ctx, &pte.pte1, 0, rwx) == 1) {
436
        ppc_hash32_store_hpte1(env, pte_offset, pte.pte1);
411
    new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
412
    if (rwx == 1) {
413
        new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */
414
    } else {
415
        /* Treat the page as read-only for now, so that a later write
416
         * will pass through this function again to set the C bit */
417
        ctx->prot &= ~PAGE_WRITE;
418
    }
419

  
420
    if (new_pte1 != pte.pte1) {
421
        ppc_hash32_store_hpte1(env, pte_offset, new_pte1);
437 422
    }
438 423

  
439 424
    /* Keep the matching PTE informations */

Also available in: Unified diff