Patchwork [7/8] target-ppc: Disentangle 64-bit hash MMU get_physical_address() paths

login
register
mail settings
Submitter David Gibson
Date Feb. 12, 2013, 2 a.m.
Message ID <1360634411-5518-8-git-send-email-david@gibson.dropbear.id.au>
Download mbox | patch
Permalink /patch/219729/
State New
Headers show

Comments

David Gibson - Feb. 12, 2013, 2 a.m.
Depending on the MSR state, for 64-bit hash MMUs, get_physical_address
can either call check_physical (which has further tests for mmu type)
or get_segment64.

This patch splits off the whole get_physical_addresss() path for 64-bit
hash MMUs into its own function, which handles real mode correctly for
such MMUs without going to check_physical and rechecking the mmu type.
Correspondingly, the 64-bit hash MMU specific path in check_physical() is
removed.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/cpu.h        |    4 ++--
 target-ppc/mmu-hash64.c |   19 +++++++++++++++++--
 target-ppc/mmu_helper.c |   27 +++++----------------------
 3 files changed, 24 insertions(+), 26 deletions(-)
Blue Swirl - Feb. 13, 2013, 8:59 p.m.
On Tue, Feb 12, 2013 at 2:00 AM, David Gibson
<david@gibson.dropbear.id.au> wrote:
> Depending on the MSR state, for 64-bit hash MMUs, get_physical_address
> can either call check_physical (which has further tests for mmu type)
> or get_segment64.
>
> This patch splits off the whole get_physical_addresss() path for 64-bit
> hash MMUs into its own function, which handles real mode correctly for
> such MMUs without going to check_physical and rechecking the mmu type.
> Correspondingly, the 64-bit hash MMU specific path in check_physical() is
> removed.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  target-ppc/cpu.h        |    4 ++--
>  target-ppc/mmu-hash64.c |   19 +++++++++++++++++--
>  target-ppc/mmu_helper.c |   27 +++++----------------------
>  3 files changed, 24 insertions(+), 26 deletions(-)
>
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index cf12632..6143142 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1153,8 +1153,8 @@ hwaddr get_pteg_offset(CPUPPCState *env, hwaddr hash, int pte_size);
>  void ppc_store_asr (CPUPPCState *env, target_ulong value);
>  int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
>  void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
> -int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
> -                  target_ulong eaddr, int rw, int type);
> +int ppc_hash64_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> +                                    target_ulong eaddr, int rw, int access_type);
>  #endif /* defined(TARGET_PPC64) */
>  #endif /* !defined(CONFIG_USER_ONLY) */
>  void ppc_store_msr (CPUPPCState *env, target_ulong value);
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 1d6425c..0f40e0a 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -349,8 +349,8 @@ static int find_pte64(CPUPPCState *env, mmu_ctx_t *ctx, int h,
>      return ret;
>  }
>
> -int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
> -                  target_ulong eaddr, int rw, int type)
> +static int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
> +                         target_ulong eaddr, int rw, int type)
>  {
>      hwaddr hash;
>      target_ulong vsid;
> @@ -456,3 +456,18 @@ int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
>
>      return ret;
>  }
> +
> +int ppc_hash64_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
> +                                    target_ulong eaddr, int rw, int access_type)
> +{
> +    bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0)
> +        || (access_type != ACCESS_CODE && msr_dr == 0);
> +
> +    if (real_mode) {
> +        ctx->raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
> +        ctx->prot = PAGE_READ | PAGE_EXEC | PAGE_WRITE;
> +        return 0;
> +    } else {
> +        return get_segment64(env, ctx, eaddr, rw, access_type);
> +    }
> +}
> diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
> index e787843..98143dd 100644
> --- a/target-ppc/mmu_helper.c
> +++ b/target-ppc/mmu_helper.c
> @@ -1361,15 +1361,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
>      case POWERPC_MMU_BOOKE:
>          ctx->prot |= PAGE_WRITE;
>          break;
> -#if defined(TARGET_PPC64)
> -    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;
> -        break;
> -#endif
> +
>      case POWERPC_MMU_SOFT_4xx_Z:
>          if (unlikely(msr_pe != 0)) {
>              /* 403 family add some particular protections,
> @@ -1394,15 +1386,10 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
>              }
>          }
>          break;
> -    case POWERPC_MMU_MPC8xx:
> -        /* XXX: TODO */
> -        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
> -        break;
> -    case POWERPC_MMU_BOOKE206:
> -        cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
> -        break;
> +
>      default:
> -        cpu_abort(env, "Unknown or invalid MMU model\n");
> +        /* Caller's checks we should never get here for other models */
> +        assert(0);

abort()

>          return -1;
>      }
>
> @@ -1443,11 +1430,7 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
>      case POWERPC_MMU_64B:
>      case POWERPC_MMU_2_06:
>      case POWERPC_MMU_2_06d:
> -        if (real_mode) {
> -            ret = check_physical(env, ctx, eaddr, rw);
> -        } else {
> -            ret = get_segment64(env, ctx, eaddr, rw, access_type);
> -        }
> +        ret = ppc_hash64_get_physical_address(env, ctx, eaddr, rw, access_type);
>          break;
>  #endif
>
> --
> 1.7.10.4
>
>

Patch

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index cf12632..6143142 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1153,8 +1153,8 @@  hwaddr get_pteg_offset(CPUPPCState *env, hwaddr hash, int pte_size);
 void ppc_store_asr (CPUPPCState *env, target_ulong value);
 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
 void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
-int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
-                  target_ulong eaddr, int rw, int type);
+int ppc_hash64_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
+                                    target_ulong eaddr, int rw, int access_type);
 #endif /* defined(TARGET_PPC64) */
 #endif /* !defined(CONFIG_USER_ONLY) */
 void ppc_store_msr (CPUPPCState *env, target_ulong value);
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 1d6425c..0f40e0a 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -349,8 +349,8 @@  static int find_pte64(CPUPPCState *env, mmu_ctx_t *ctx, int h,
     return ret;
 }
 
-int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
-                  target_ulong eaddr, int rw, int type)
+static int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
+                         target_ulong eaddr, int rw, int type)
 {
     hwaddr hash;
     target_ulong vsid;
@@ -456,3 +456,18 @@  int get_segment64(CPUPPCState *env, mmu_ctx_t *ctx,
 
     return ret;
 }
+
+int ppc_hash64_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
+                                    target_ulong eaddr, int rw, int access_type)
+{
+    bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0)
+        || (access_type != ACCESS_CODE && msr_dr == 0);
+
+    if (real_mode) {
+        ctx->raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
+        ctx->prot = PAGE_READ | PAGE_EXEC | PAGE_WRITE;
+        return 0;
+    } else {
+        return get_segment64(env, ctx, eaddr, rw, access_type);
+    }
+}
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index e787843..98143dd 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1361,15 +1361,7 @@  static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
     case POWERPC_MMU_BOOKE:
         ctx->prot |= PAGE_WRITE;
         break;
-#if defined(TARGET_PPC64)
-    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;
-        break;
-#endif
+
     case POWERPC_MMU_SOFT_4xx_Z:
         if (unlikely(msr_pe != 0)) {
             /* 403 family add some particular protections,
@@ -1394,15 +1386,10 @@  static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
             }
         }
         break;
-    case POWERPC_MMU_MPC8xx:
-        /* XXX: TODO */
-        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
-        break;
-    case POWERPC_MMU_BOOKE206:
-        cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
-        break;
+
     default:
-        cpu_abort(env, "Unknown or invalid MMU model\n");
+        /* Caller's checks we should never get here for other models */
+        assert(0);
         return -1;
     }
 
@@ -1443,11 +1430,7 @@  static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
     case POWERPC_MMU_64B:
     case POWERPC_MMU_2_06:
     case POWERPC_MMU_2_06d:
-        if (real_mode) {
-            ret = check_physical(env, ctx, eaddr, rw);
-        } else {
-            ret = get_segment64(env, ctx, eaddr, rw, access_type);
-        }
+        ret = ppc_hash64_get_physical_address(env, ctx, eaddr, rw, access_type);
         break;
 #endif