aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/mmu_helper.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-06-18 19:56:25 +0000
committerAlexander Graf <agraf@suse.de>2012-06-24 01:04:44 +0200
commit4656e1f01289cc3aa20986deb6a407165826abe5 (patch)
treea8eec4470ce0817b5c38f01b1e365d759419c3bb /target-ppc/mmu_helper.c
parent77c2cf33fe8d272e5375b55c588202a18af0e27c (diff)
ppc64: Rudimentary Support for extra page sizes on server CPUs
More recent Power server chips (i.e. based on the 64 bit hash MMU) support more than just the traditional 4k and 16M page sizes. This can get quite complicated, because which page sizes are supported, which combinations are supported within an MMU segment and how these page sizes are encoded both in the SLB entry and the hash PTE can vary depending on the CPU model (they are not specified by the architecture). In addition the firmware or hypervisor may not permit use of certain page sizes, for various reasons. Whether various page sizes are supported on KVM, for example, depends on whether the PR or HV variant of KVM is in use, and on the page size of the memory backing the guest's RAM. This patch adds information to the CPUState and cpu defs to describe the supported page sizes and encodings. Since TCG does not yet support any extended page sizes, we just set this to NULL in the static CPU definitions, expanding this to the default 4k and 16M page sizes when we initialize the cpu state. When using KVM, however, we instead determine available page sizes using the new KVM_PPC_GET_SMMU_INFO call. For old kernels without that call, we use some defaults, with some guesswork which should do the right thing for existing HV and PR implementations. The fallback might not be correct for future versions, but that's ok, because they'll have KVM_PPC_GET_SMMU_INFO. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/mmu_helper.c')
-rw-r--r--target-ppc/mmu_helper.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index c4e79d9ca7..d2664acef0 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1634,6 +1634,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
mmubooks_dump_mmu(f, cpu_fprintf, env);
break;
#endif
@@ -1664,6 +1665,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
/* Real address are 60 bits long */
ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
ctx->prot |= PAGE_WRITE;
@@ -1745,6 +1747,7 @@ int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
#endif
if (ret < 0) {
/* We didn't match any BAT entry or don't have BATs */
@@ -1886,6 +1889,7 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
#endif
env->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x40000000;
@@ -1997,6 +2001,7 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
#endif
env->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
@@ -2326,6 +2331,7 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
#endif /* defined(TARGET_PPC64) */
tlb_flush(env, 1);
break;
@@ -2395,6 +2401,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06d:
/* tlbie invalidate TLBs for all segments */
/* XXX: given the fact that there are too many segments to invalidate,
* and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,