diff mbox series

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

Message ID 20210803041443.55452-17-richard.henderson@linaro.org
State Superseded
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(-)

-- 
2.25.1

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;
         }
     }