All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tobias Roehmel <quic_trohmel@quicinc.com>
To: <qemu-devel@nongnu.org>
Cc: peter.maydell@linaro.org, "Tobias Röhmel" <quic_trohmel@quicinc.com>
Subject: [PATCH 09/11] target/arm: Add PMSAv8r functionality
Date: Thu, 14 Jul 2022 16:53:53 +0200	[thread overview]
Message-ID: <20220714145355.7225-10-quic_trohmel@quicinc.com> (raw)
In-Reply-To: <20220714145355.7225-1-quic_trohmel@quicinc.com>

From: Tobias Röhmel <quic_trohmel@quicinc.com>

Add PMSAv8r translation that is used by the ARM Cortex-R52.

Signed-off-by: Tobias Röhmel <quic_trohmel@quicinc.com>
---
 target/arm/ptw.c | 171 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 150 insertions(+), 21 deletions(-)

diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index c4f5721012..c7e37c66d0 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -140,6 +140,9 @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
              */
             return true;
         }
+    } else if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        return !(regime_sctlr(env, mmu_idx) & SCTLR_M) ||
+        (!(regime_el(env, mmu_idx) == 2) && arm_hcr_el2_eff(env) & HCR_TGE);
     }
 
     hcr_el2 = arm_hcr_el2_eff(env);
@@ -1504,6 +1507,8 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     if (arm_feature(env, ARM_FEATURE_M)) {
         return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
             & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
+    } else if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        return false;
     } else {
         return regime_sctlr(env, mmu_idx) & SCTLR_BR;
     }
@@ -1698,6 +1703,77 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
     return !(*prot & (1 << access_type));
 }
 
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
+                             uint32_t secure)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            return env->pmsav8.hprbarn;
+        } else {
+            return env->pmsav8.prbarn;
+        }
+    } else {
+         return env->pmsav8.rbar[secure];
+    }
+}
+
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
+                             uint32_t secure)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            return env->pmsav8.hprlarn;
+        } else {
+            return env->pmsav8.prlarn;
+        }
+    } else {
+        return env->pmsav8.rlar[secure];
+    }
+}
+
+static inline void get_phys_addr_pmsav8_default(CPUARMState *env,
+                                                ARMMMUIdx mmu_idx,
+                                                uint32_t address, int *prot)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        *prot = PAGE_READ | PAGE_WRITE;
+        if (address <= 0x7FFFFFFF) {
+            *prot |= PAGE_EXEC;
+        }
+        if ((regime_el(env, mmu_idx) == 2)
+            && (regime_sctlr(env, mmu_idx) & SCTLR_WXN)
+            && (regime_sctlr(env, mmu_idx) & SCTLR_M)) {
+            *prot &= ~PAGE_EXEC;
+        }
+    } else {
+        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+    }
+}
+
+static bool pmsav8_fault(bool hit, CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (regime_el(env, mmu_idx) == 2) {
+            if (!hit && (mmu_idx != ARMMMUIdx_E2)) {
+                return true;
+            } else if (!hit && (mmu_idx == ARMMMUIdx_E2)
+                       &&!(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
+                return true;
+            }
+        } else {
+            if (!hit && (mmu_idx != ARMMMUIdx_Stage1_E1)) {
+                return true;
+            } else if (!hit && (mmu_idx == ARMMMUIdx_Stage1_E1)
+                       &&!(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
+                return true;
+            }
+        }
+        return false;
+    } else {
+        return !hit;
+    }
+}
+
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
                        MMUAccessType access_type, ARMMMUIdx mmu_idx,
                        hwaddr *phys_ptr, MemTxAttrs *txattrs,
@@ -1730,6 +1806,12 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         *mregion = -1;
     }
 
+    if (arm_feature(env, ARM_FEATURE_V8_R)) {
+        if (mmu_idx == ARMMMUIdx_Stage2) {
+            fi->stage2 = true;
+        }
+    }
+
     /*
      * Unlike the ARM ARM pseudocode, we don't need to check whether this
      * was an exception vector read from the vector table (which is always
@@ -1746,17 +1828,26 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
             hit = true;
         }
 
+        uint32_t bitmask;
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            bitmask = 0x3f;
+        } else {
+            bitmask = 0x1f;
+        }
+
+
         for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
             /* region search */
             /*
-             * Note that the base address is bits [31:5] from the register
-             * with bits [4:0] all zeroes, but the limit address is bits
-             * [31:5] from the register with bits [4:0] all ones.
+             * Note that the base address is bits [31:x] from the register
+             * with bits [x-1:0] all zeroes, but the limit address is bits
+             * [31:x] from the register with bits [x:0] all ones. Where x is
+             * 5 for Cortex-M and 6 for Cortex-R
              */
-            uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
-            uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
+            uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
+            uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
 
-            if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
+            if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
                 /* Region disabled */
                 continue;
             }
@@ -1799,22 +1890,25 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         }
     }
 
-    if (!hit) {
-        /* background fault */
-        fi->type = ARMFault_Background;
+    if (pmsav8_fault(hit, env, mmu_idx)) {
+        fi->type = ARMFault_Permission;
+        fi->level = 0;
         return true;
     }
 
     if (matchregion == -1) {
         /* hit using the background region */
-        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+        get_phys_addr_pmsav8_default(env, mmu_idx, address, prot);
     } else {
-        uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
-        uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
+        uint32_t ap = extract32(regime_rbar(env,
+                                mmu_idx, secure)[matchregion], 1, 2);
+        uint32_t xn = extract32(regime_rbar(env,
+                                mmu_idx, secure)[matchregion], 0, 1);
         bool pxn = false;
 
         if (arm_feature(env, ARM_FEATURE_V8_1M)) {
-            pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
+            pxn = extract32(regime_rlar(env,
+                            mmu_idx, secure)[matchregion], 4, 1);
         }
 
         if (m_is_system_region(env, address)) {
@@ -1822,14 +1916,42 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
             xn = 1;
         }
 
-        *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        if (arm_feature(env, ARM_FEATURE_V8_R)) {
+            if (regime_el(env, mmu_idx) == 2) {
+                *prot = simple_ap_to_rw_prot_is_user(ap,
+                                                mmu_idx != ARMMMUIdx_E2);
+            } else {
+                *prot = simple_ap_to_rw_prot_is_user(ap,
+                                                mmu_idx != ARMMMUIdx_Stage1_E1);
+            }
+
+            if (regime_sctlr(env, mmu_idx) & SCTLR_WXN
+                && (*prot & PAGE_WRITE)) {
+                xn = 0x1;
+            }
+
+            if ((regime_el(env, mmu_idx) == 1) && regime_sctlr(env, mmu_idx)
+                 & SCTLR_UWXN && (ap == 0x1)) {
+                xn = 0x1;
+            }
+
+            uint8_t attrindx = extract32(regime_rlar(env,
+                                         mmu_idx, secure)[matchregion], 1, 3);
+            uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
+            uint8_t sh = extract32(regime_rlar(env,
+                                   mmu_idx, secure)[matchregion], 3, 2);
+            assert(attrindx <= 4);
+            cacheattrs->is_s2_format = false;
+            cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
+            cacheattrs->shareability = sh;
+        } else {
+            *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        }
+
         if (*prot && !xn && !(pxn && !is_user)) {
             *prot |= PAGE_EXEC;
         }
-        /*
-         * We don't need to look the attribute up in the MAIR0/MAIR1
-         * registers because that only tells us about cacheability.
-         */
+
         if (mregion) {
             *mregion = matchregion;
         }
@@ -2342,9 +2464,16 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
             is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
 
             /* S1 is done. Now do S2 translation.  */
-            ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
-                                     phys_ptr, attrs, &s2_prot,
-                                     page_size, fi, &cacheattrs2);
+            if (arm_feature(env, ARM_FEATURE_V8_R)) {
+                ret = get_phys_addr_pmsav8(env, ipa, access_type, s2_mmu_idx,
+                                       phys_ptr, attrs, &s2_prot, page_size,
+                                       fi, &cacheattrs2);
+            } else {
+                ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
+                                      is_el0, phys_ptr, attrs, &s2_prot,
+                                      page_size, fi, &cacheattrs2);
+            }
+
             fi->s2addr = ipa;
             /* Combine the S1 and S2 perms.  */
             *prot &= s2_prot;
-- 
2.25.1



  parent reply	other threads:[~2022-07-14 15:18 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-14 14:53 [PATCH 00/11] Add Cortex-R52 Tobias Roehmel
2022-07-14 14:53 ` [PATCH 01/11] target/arm: Add ARM_FEATURE_V8_R Tobias Roehmel
2022-07-14 15:16   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 02/11] target/arm: Add ARM Cortex-R52 cpu Tobias Roehmel
2022-07-14 15:23   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 03/11] target/arm: Add v8R MIDR register Tobias Roehmel
2022-07-14 15:15   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 04/11] target/arm: Make RVBAR available for non AARCH64 CPUs Tobias Roehmel
2022-07-14 15:28   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 05/11] target/arm: Make stage_2_format for cache attributes optional Tobias Roehmel
2022-07-14 14:53 ` [PATCH 06/11] target/arm: Add ARMCacheAttrs to the signature of pmsav8_mpu_lookup Tobias Roehmel
2022-07-14 14:53 ` [PATCH 07/11] target/arm: Enable TTBCR_EAE for ARM_FEATURE_V8_R Tobias Roehmel
2022-07-14 15:34   ` Peter Maydell
2022-07-14 14:53 ` [PATCH 08/11] target/arm Add PMSAv8r registers Tobias Roehmel
2022-07-14 14:53 ` Tobias Roehmel [this message]
2022-07-14 14:53 ` [PATCH 10/11] target/arm: Make SPSR_hyp accessible for Cortex-R52 Tobias Roehmel
2022-07-14 15:46   ` Peter Maydell
2022-07-14 16:52     ` Peter Maydell
2022-07-14 14:53 ` [PATCH 11/11] hw/arm: Add R52 machine Tobias Roehmel
2022-07-14 15:53   ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220714145355.7225-10-quic_trohmel@quicinc.com \
    --to=quic_trohmel@quicinc.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.