diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/mmu-hash64.c | 35 | ||||
-rw-r--r-- | target-ppc/mmu-hash64.h | 3 |
2 files changed, 38 insertions, 0 deletions
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 565a0f484a..6d110ee342 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -513,6 +513,41 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps, return 0; /* Bad page size encoding */ } +unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, + uint64_t pte0, uint64_t pte1, + unsigned *seg_page_shift) +{ + CPUPPCState *env = &cpu->env; + int i; + + if (!(pte0 & HPTE64_V_LARGE)) { + *seg_page_shift = 12; + return 12; + } + + /* + * The encodings in env->sps need to be carefully chosen so that + * this gives an unambiguous result. + */ + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { + const struct ppc_one_seg_page_size *sps = &env->sps.sps[i]; + unsigned shift; + + if (!sps->page_shift) { + break; + } + + shift = hpte_page_shift(sps, pte0, pte1); + if (shift) { + *seg_page_shift = sps->page_shift; + return shift; + } + } + + *seg_page_shift = 0; + return 0; +} + int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr, int rwx, int mmu_idx) { diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index 293a9514db..34cf975484 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -16,6 +16,9 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index, void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, target_ulong pte_index, target_ulong pte0, target_ulong pte1); +unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, + uint64_t pte0, uint64_t pte1, + unsigned *seg_page_shift); #endif /* |