aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-07-24 18:43:34 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-08-31 11:07:02 +0100
commitcb0929bb1344d095c9e7980e3803562b8b3cd604 (patch)
tree9aa409f25a2d525362c02d60938b6e5c01fc4ccb
parentb8f7959f28c4f36496bc0a694fa28bf5078152c5 (diff)
hw/arm/armv7m: Add mpu-ns-regions and mpu-s-regions properties
M-profile CPUs generally allow configuration of the number of MPU regions that they have. We don't currently model this, so our implementations of some of the board models provide CPUs with the wrong number of regions. RTOSes like Zephyr that hardcode the expected number of regions may therefore not run on the model if they are set up to run on real hardware. Add properties mpu-ns-regions and mpu-s-regions to the ARMV7M object, matching the ability of hardware to configure the number of Secure and NonSecure regions separately. Our actual CPU implementation doesn't currently support that, and it happens that none of the MPS boards we model set the number of regions differently for Secure vs NonSecure, so we provide an interface to the boards and SoCs that won't need to change if we ever do add that functionality in future, but make it an error to configure the two properties to different values. (The property name on the CPU is the somewhat misnamed-for-M-profile "pmsav7-dregion", so we don't follow that naming convention for the properties here. The TRM doesn't say what the CPU configuration variable names are, so we pick something, and follow the lowercase convention we already have for properties here.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230724174335.2150499-3-peter.maydell@linaro.org
-rw-r--r--hw/arm/armv7m.c21
-rw-r--r--include/hw/arm/armv7m.h8
2 files changed, 29 insertions, 0 deletions
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 50a9507c0b..bf173b10b8 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -335,6 +335,25 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
}
/*
+ * Real M-profile hardware can be configured with a different number of
+ * MPU regions for Secure vs NonSecure. QEMU's CPU implementation doesn't
+ * support that yet, so catch attempts to select that.
+ */
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
+ s->mpu_ns_regions != s->mpu_s_regions) {
+ error_setg(errp,
+ "mpu-ns-regions and mpu-s-regions properties must have the same value");
+ return;
+ }
+ if (s->mpu_ns_regions != UINT_MAX &&
+ object_property_find(OBJECT(s->cpu), "pmsav7-dregion")) {
+ if (!object_property_set_uint(OBJECT(s->cpu), "pmsav7-dregion",
+ s->mpu_ns_regions, errp)) {
+ return;
+ }
+ }
+
+ /*
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
* have one. Similarly, tell the NVIC where its CPU is.
*/
@@ -530,6 +549,8 @@ static Property armv7m_properties[] = {
false),
DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
+ DEFINE_PROP_UINT32("mpu-ns-regions", ARMv7MState, mpu_ns_regions, UINT_MAX),
+ DEFINE_PROP_UINT32("mpu-s-regions", ARMv7MState, mpu_s_regions, UINT_MAX),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
index b7ba0ff409..e2cebbd15c 100644
--- a/include/hw/arm/armv7m.h
+++ b/include/hw/arm/armv7m.h
@@ -52,6 +52,12 @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
* + Property "vfp": enable VFP (forwarded to CPU object)
* + Property "dsp": enable DSP (forwarded to CPU object)
* + Property "enable-bitband": expose bitbanded IO
+ * + Property "mpu-ns-regions": number of Non-Secure MPU regions (forwarded
+ * to CPU object pmsav7-dregion property; default is whatever the default
+ * for the CPU is)
+ * + Property "mpu-s-regions": number of Secure MPU regions (default is
+ * whatever the default for the CPU is; must currently be set to the same
+ * value as mpu-ns-regions if the CPU implements the Security Extension)
* + Clock input "refclk" is the external reference clock for the systick timers
* + Clock input "cpuclk" is the main CPU clock
*/
@@ -95,6 +101,8 @@ struct ARMv7MState {
Object *idau;
uint32_t init_svtor;
uint32_t init_nsvtor;
+ uint32_t mpu_ns_regions;
+ uint32_t mpu_s_regions;
bool enable_bitband;
bool start_powered_off;
bool vfp;