summary refs log tree commit diff stats
path: root/target/arm/helper.c
diff options
context:
space:
mode:
authorMichael Davidsaver <mdavidsaver@gmail.com>2017-06-02 11:51:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-02 11:51:48 +0100
commit29c483a506070e8f554c77d22686f405e30b9114 (patch)
treed0c36f71539d865a154f8c1c7ba4ce6c76ef14ab /target/arm/helper.c
parent5dd0641d234e355597be62e5279d8a519c831625 (diff)
downloadfocaccia-qemu-29c483a506070e8f554c77d22686f405e30b9114.tar.gz
focaccia-qemu-29c483a506070e8f554c77d22686f405e30b9114.zip
arm: add MPU support to M profile CPUs
The M series MPU is almost the same as the already implemented R
profile MPU (v7 PMSA).  So all we need to implement here is the MPU
register interface in the system register space.

This implementation has the same restriction as the R profile MPU
that it doesn't permit regions to be sized down smaller than 1K.

We also do not yet implement support for MPU_CTRL.HFNMIENA; this
bit should if zero disable use of the MPU when running HardFault,
NMI or with FAULTMASK set to 1 (ie at an execution priority of
less than zero) -- if the MPU is enabled we don't treat these
cases any differently.

Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
Message-id: 1493122030-32191-13-git-send-email-peter.maydell@linaro.org
[PMM: Keep all the bits in mpu_ctrl field, rather than
 using SCTLR bits for them; drop broken HFNMIENA support;
 various cleanup]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c9d94c56cd..674b52dea0 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7076,6 +7076,10 @@ static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
 static inline bool regime_translation_disabled(CPUARMState *env,
                                                ARMMMUIdx mmu_idx)
 {
+    if (arm_feature(env, ARM_FEATURE_M)) {
+        return !(env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_ENABLE_MASK);
+    }
+
     if (mmu_idx == ARMMMUIdx_S2NS) {
         return (env->cp15.hcr_el2 & HCR_VM) == 0;
     }
@@ -8205,6 +8209,25 @@ static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
     }
 }
 
+static bool pmsav7_use_background_region(ARMCPU *cpu,
+                                         ARMMMUIdx mmu_idx, bool is_user)
+{
+    /* Return true if we should use the default memory map as a
+     * "background" region if there are no hits against any MPU regions.
+     */
+    CPUARMState *env = &cpu->env;
+
+    if (is_user) {
+        return false;
+    }
+
+    if (arm_feature(env, ARM_FEATURE_M)) {
+        return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
+    } else {
+        return regime_sctlr(env, mmu_idx) & SCTLR_BR;
+    }
+}
+
 static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                                  int access_type, ARMMMUIdx mmu_idx,
                                  hwaddr *phys_ptr, int *prot, uint32_t *fsr)
@@ -8292,7 +8315,7 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
         }
 
         if (n == -1) { /* no hits */
-            if (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
+            if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
                 /* background fault */
                 *fsr = 0;
                 return true;