Commit 157f6c69ed for qemu.org
commit 157f6c69edd0627f5f78f1f14ea0d831b0948c69
Author: Gilles Grimaud <gilles.grimaud@univ-lille.fr>
Date: Mon Sep 14 21:23:22 2026 +0200
target/arm: extend PMSAv7 support to v6-M CPUs
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 <peter.maydell@linaro.org>
Signed-off-by: Gilles Grimaud <gilles.grimaud@univ-lille.fr>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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);