From 5e14b33c65f66e716b1e882044a29b2846b33b8d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 4 Mar 2018 21:04:39 -0500 Subject: [PATCH] target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security extensions are enabled. We can freely add more items to vmstate_m_security without breaking migration compatibility, because no CPU currently has the ARM_FEATURE_M_SECURITY bit enabled and so this subsection is not yet used by anything. Backports commit 62c58ee0b24eafb44c06402fe059fbd7972eb409 from qemu --- qemu/target/arm/cpu.c | 26 ++++++++++++++++++++------ qemu/target/arm/cpu.h | 4 ++-- qemu/target/arm/helper.c | 11 ++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 5237b848..9ef5a465 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -234,10 +234,20 @@ static void arm_cpu_reset(CPUState *s) if (arm_feature(env, ARM_FEATURE_PMSA)) { if (cpu->pmsav7_dregion > 0) { if (arm_feature(env, ARM_FEATURE_V8)) { - memset(env->pmsav8.rbar, 0, - sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion); - memset(env->pmsav8.rlar, 0, - sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion); + memset(env->pmsav8.rbar[M_REG_NS], 0, + sizeof(*env->pmsav8.rbar[M_REG_NS]) + * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar[M_REG_NS], 0, + sizeof(*env->pmsav8.rlar[M_REG_NS]) + * cpu->pmsav7_dregion); + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + memset(env->pmsav8.rbar[M_REG_S], 0, + sizeof(*env->pmsav8.rbar[M_REG_S]) + * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar[M_REG_S], 0, + sizeof(*env->pmsav8.rlar[M_REG_S]) + * cpu->pmsav7_dregion); + } } else if (arm_feature(env, ARM_FEATURE_V7)) { memset(env->pmsav7.drbar, 0, sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); @@ -615,8 +625,12 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err if (nr) { if (arm_feature(env, ARM_FEATURE_V8)) { /* PMSAv8 */ - env->pmsav8.rbar = g_new0(uint32_t, nr); - env->pmsav8.rlar = g_new0(uint32_t, nr); + env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr); + env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr); + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr); + env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr); + } } else { env->pmsav7.drbar = g_new0(uint32_t, nr); env->pmsav7.drsr = g_new0(uint32_t, nr); diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index d380a3be..384557f2 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -548,8 +548,8 @@ typedef struct CPUARMState { * pmsav7.rnr (region number register) * pmsav7_dregion (number of configured regions) */ - uint32_t *rbar; - uint32_t *rlar; + uint32_t *rbar[2]; + uint32_t *rlar[2]; uint32_t mair0[2]; uint32_t mair1[2]; } pmsav8; diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index 734d2705..6b0d59e0 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -7707,6 +7707,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, { ARMCPU *cpu = arm_env_get_cpu(env); bool is_user = regime_is_user(env, mmu_idx); + uint32_t secure = regime_is_secure(env, mmu_idx); int n; int matchregion = -1; bool hit = false; @@ -7733,10 +7734,10 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, * with bits [4:0] all zeroes, but the limit address is bits * [31:5] from the register with bits [4:0] all ones. */ - uint32_t base = env->pmsav8.rbar[n] & ~0x1f; - uint32_t limit = env->pmsav8.rlar[n] | 0x1f; + uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f; + uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f; - if (!(env->pmsav8.rlar[n] & 0x1)) { + if (!(env->pmsav8.rlar[secure][n] & 0x1)) { /* Region disabled */ continue; } @@ -7785,8 +7786,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, /* hit using the background region */ get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); } else { - uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2); - uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1); + uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2); + uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1); if (m_is_system_region(env, address)) { /* System space is always execute never */