QEMU conditions PMSAv7 storage, reset, allocation, the pmsav7-dregion property, migration and address translation on ARM_FEATURE_V7, which prevents the Armv6-M MPU from being used. The checks are widened to also accept ARM_FEATURE_M while preserving the PMSAv8 path for v8-M CPUs (PMSAv8 is tested first and the migration vmstate excludes v8-M with !ARM_FEATURE_V8). This lets a Cortex-M0+ declare and use its MPU regions without setting ARM_FEATURE_V7, while v8-M CPUs continue to use PMSAv8 storage and migration.
Suggested-by: Peter Maydell <[email protected]> Signed-off-by: Gilles Grimaud <[email protected]> --- target/arm/cpu.c | 12 +++++++++--- target/arm/machine.c | 3 ++- target/arm/ptw.c | 3 ++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 77aa78f00e..f58a1db843 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -617,7 +617,8 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type) sizeof(*env->pmsav8.rlar[M_REG_S]) * cpu->pmsav7_dregion); } - } else if (arm_feature(env, ARM_FEATURE_V7)) { + } else if (arm_feature(env, ARM_FEATURE_V7) || + arm_feature(env, ARM_FEATURE_M)) { memset(env->pmsav7.drbar, 0, sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); memset(env->pmsav7.drsr, 0, @@ -1656,7 +1657,11 @@ static void arm_cpu_post_init(Object *obj) #ifndef CONFIG_USER_ONLY if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property); - if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { + /* + * QEMU's PMSAv7 state also models the Armv6-M MPU register layout. + */ + if (arm_feature(&cpu->env, ARM_FEATURE_V7) || + arm_feature(&cpu->env, ARM_FEATURE_M)) { qdev_property_add_static(DEVICE(obj), &arm_cpu_pmsav7_dregion_property); } @@ -2332,7 +2337,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7)) { + (arm_feature(env, ARM_FEATURE_V7) || + arm_feature(env, ARM_FEATURE_M))) { uint32_t nr = cpu->pmsav7_dregion; if (nr > 0xff) { diff --git a/target/arm/machine.c b/target/arm/machine.c index 7005f4e5d7..53a2734d25 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -584,7 +584,8 @@ static bool pmsav7_needed(void *opaque) CPUARMState *env = &cpu->env; return arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7) && + (arm_feature(env, ARM_FEATURE_V7) || + arm_feature(env, ARM_FEATURE_M)) && !arm_feature(env, ARM_FEATURE_V8); } diff --git a/target/arm/ptw.c b/target/arm/ptw.c index cb9e73fc0a..f537502d3b 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -3908,7 +3908,8 @@ static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw, /* PMSAv8 */ ret = get_phys_addr_pmsav8(env, ptw, address, access_type, result, fi); - } else if (arm_feature(env, ARM_FEATURE_V7)) { + } else if (arm_feature(env, ARM_FEATURE_V7) || + arm_feature(env, ARM_FEATURE_M)) { /* PMSAv7 */ ret = get_phys_addr_pmsav7(env, ptw, address, access_type, result, fi); -- 2.55.0
