@@ -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;
@@ -334,6 +334,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(),
};