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