diff mbox series

[v2,16/55] target/sparc: Split out build_sfsr

Message ID 20210803041443.55452-17-richard.henderson@linaro.org (mailing list archive)
State New, archived
Headers show
Series Unaligned access for user-only | expand

Commit Message

Richard Henderson Aug. 3, 2021, 4:14 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/sparc/mmu_helper.c | 72 +++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 26 deletions(-)

Comments

Mark Cave-Ayland Aug. 18, 2021, 8:38 a.m. UTC | #1
On 03/08/2021 05:14, Richard Henderson wrote:

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/sparc/mmu_helper.c | 72 +++++++++++++++++++++++++--------------
>   1 file changed, 46 insertions(+), 26 deletions(-)
> 
> diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
> index a44473a1c7..5b2fda534a 100644
> --- a/target/sparc/mmu_helper.c
> +++ b/target/sparc/mmu_helper.c
> @@ -526,16 +526,60 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
>       return 0;
>   }
>   
> +static uint64_t build_sfsr(CPUSPARCState *env, int mmu_idx, int rw)
> +{
> +    uint64_t sfsr = SFSR_VALID_BIT;
> +
> +    switch (mmu_idx) {
> +    case MMU_PHYS_IDX:
> +        sfsr |= SFSR_CT_NOTRANS;
> +        break;
> +    case MMU_USER_IDX:
> +    case MMU_KERNEL_IDX:
> +        sfsr |= SFSR_CT_PRIMARY;
> +        break;
> +    case MMU_USER_SECONDARY_IDX:
> +    case MMU_KERNEL_SECONDARY_IDX:
> +        sfsr |= SFSR_CT_SECONDARY;
> +        break;
> +    case MMU_NUCLEUS_IDX:
> +        sfsr |= SFSR_CT_NUCLEUS;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    if (rw == 1) {
> +        sfsr |= SFSR_WRITE_BIT;
> +    } else if (rw == 4) {
> +        sfsr |= SFSR_NF_BIT;
> +    }
> +
> +    if (env->pstate & PS_PRIV) {
> +        sfsr |= SFSR_PR_BIT;
> +    }
> +
> +    if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
> +        sfsr |= SFSR_OW_BIT; /* overflow (not read before another fault) */
> +    }
> +
> +    /* FIXME: ASI field in SFSR must be set */
> +
> +    return sfsr;
> +}
> +
>   static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
>                                        int *prot, MemTxAttrs *attrs,
>                                        target_ulong address, int rw, int mmu_idx)
>   {
>       CPUState *cs = env_cpu(env);
>       unsigned int i;
> +    uint64_t sfsr;
>       uint64_t context;
> -    uint64_t sfsr = 0;
>       bool is_user = false;
>   
> +    sfsr = build_sfsr(env, mmu_idx, rw);
> +
>       switch (mmu_idx) {
>       case MMU_PHYS_IDX:
>           g_assert_not_reached();
> @@ -544,29 +588,18 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
>           /* fallthru */
>       case MMU_KERNEL_IDX:
>           context = env->dmmu.mmu_primary_context & 0x1fff;
> -        sfsr |= SFSR_CT_PRIMARY;
>           break;
>       case MMU_USER_SECONDARY_IDX:
>           is_user = true;
>           /* fallthru */
>       case MMU_KERNEL_SECONDARY_IDX:
>           context = env->dmmu.mmu_secondary_context & 0x1fff;
> -        sfsr |= SFSR_CT_SECONDARY;
>           break;
> -    case MMU_NUCLEUS_IDX:
> -        sfsr |= SFSR_CT_NUCLEUS;
> -        /* FALLTHRU */
>       default:
>           context = 0;
>           break;
>       }
>   
> -    if (rw == 1) {
> -        sfsr |= SFSR_WRITE_BIT;
> -    } else if (rw == 4) {
> -        sfsr |= SFSR_NF_BIT;
> -    }
> -
>       for (i = 0; i < 64; i++) {
>           /* ctx match, vaddr match, valid? */
>           if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
> @@ -616,22 +649,9 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
>                   return 0;
>               }
>   
> -            if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
> -                sfsr |= SFSR_OW_BIT; /* overflow (not read before
> -                                        another fault) */
> -            }
> -
> -            if (env->pstate & PS_PRIV) {
> -                sfsr |= SFSR_PR_BIT;
> -            }
> -
> -            /* FIXME: ASI field in SFSR must be set */
> -            env->dmmu.sfsr = sfsr | SFSR_VALID_BIT;
> -
> +            env->dmmu.sfsr = sfsr;
>               env->dmmu.sfar = address; /* Fault address register */
> -
>               env->dmmu.tag_access = (address & ~0x1fffULL) | context;
> -
>               return 1;
>           }
>       }

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.
diff mbox series

Patch

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index a44473a1c7..5b2fda534a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -526,16 +526,60 @@  static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
     return 0;
 }
 
+static uint64_t build_sfsr(CPUSPARCState *env, int mmu_idx, int rw)
+{
+    uint64_t sfsr = SFSR_VALID_BIT;
+
+    switch (mmu_idx) {
+    case MMU_PHYS_IDX:
+        sfsr |= SFSR_CT_NOTRANS;
+        break;
+    case MMU_USER_IDX:
+    case MMU_KERNEL_IDX:
+        sfsr |= SFSR_CT_PRIMARY;
+        break;
+    case MMU_USER_SECONDARY_IDX:
+    case MMU_KERNEL_SECONDARY_IDX:
+        sfsr |= SFSR_CT_SECONDARY;
+        break;
+    case MMU_NUCLEUS_IDX:
+        sfsr |= SFSR_CT_NUCLEUS;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    if (rw == 1) {
+        sfsr |= SFSR_WRITE_BIT;
+    } else if (rw == 4) {
+        sfsr |= SFSR_NF_BIT;
+    }
+
+    if (env->pstate & PS_PRIV) {
+        sfsr |= SFSR_PR_BIT;
+    }
+
+    if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
+        sfsr |= SFSR_OW_BIT; /* overflow (not read before another fault) */
+    }
+
+    /* FIXME: ASI field in SFSR must be set */
+
+    return sfsr;
+}
+
 static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
                                      int *prot, MemTxAttrs *attrs,
                                      target_ulong address, int rw, int mmu_idx)
 {
     CPUState *cs = env_cpu(env);
     unsigned int i;
+    uint64_t sfsr;
     uint64_t context;
-    uint64_t sfsr = 0;
     bool is_user = false;
 
+    sfsr = build_sfsr(env, mmu_idx, rw);
+
     switch (mmu_idx) {
     case MMU_PHYS_IDX:
         g_assert_not_reached();
@@ -544,29 +588,18 @@  static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
         /* fallthru */
     case MMU_KERNEL_IDX:
         context = env->dmmu.mmu_primary_context & 0x1fff;
-        sfsr |= SFSR_CT_PRIMARY;
         break;
     case MMU_USER_SECONDARY_IDX:
         is_user = true;
         /* fallthru */
     case MMU_KERNEL_SECONDARY_IDX:
         context = env->dmmu.mmu_secondary_context & 0x1fff;
-        sfsr |= SFSR_CT_SECONDARY;
         break;
-    case MMU_NUCLEUS_IDX:
-        sfsr |= SFSR_CT_NUCLEUS;
-        /* FALLTHRU */
     default:
         context = 0;
         break;
     }
 
-    if (rw == 1) {
-        sfsr |= SFSR_WRITE_BIT;
-    } else if (rw == 4) {
-        sfsr |= SFSR_NF_BIT;
-    }
-
     for (i = 0; i < 64; i++) {
         /* ctx match, vaddr match, valid? */
         if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
@@ -616,22 +649,9 @@  static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
                 return 0;
             }
 
-            if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
-                sfsr |= SFSR_OW_BIT; /* overflow (not read before
-                                        another fault) */
-            }
-
-            if (env->pstate & PS_PRIV) {
-                sfsr |= SFSR_PR_BIT;
-            }
-
-            /* FIXME: ASI field in SFSR must be set */
-            env->dmmu.sfsr = sfsr | SFSR_VALID_BIT;
-
+            env->dmmu.sfsr = sfsr;
             env->dmmu.sfar = address; /* Fault address register */
-
             env->dmmu.tag_access = (address & ~0x1fffULL) | context;
-
             return 1;
         }
     }