summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2020-05-13 15:22:48 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-22 19:21:55 +0000
commit38df3878f8d7d4bc149faaa0884f0ded501b491c (patch)
treef6d24b5542e88464a9844885951ae036293d11da /core
parent43c2f29347bc0e98ef877afb720977d594461473 (diff)
downloadchrome-ec-38df3878f8d7d4bc149faaa0884f0ded501b491c.tar.gz
cortex-m: Configure rollback MPU based on number of regions
Rollback MPU support was initially added for the Cortex-M7, which can support 16 MPU regions. REGION_ROLLBACK was defined as MPU region 10. For the Cortex-M4, there are at most 8 regions, so we have to repurpose some of the existing (unused) regions. BRANCH=none BUG=b:155229277, b:156501835 TEST=Compile and flash "rollback" test on dragonclaw with region 0 On console: "runtest" => Reboots with "Data access violation, mfar = 8020000" => PASS TEST=Compile and flash "rollback" test on dragonclaw with region 1 On console: "runtest" => Reboots with "Data access violation, mfar = 8040000" => PASS TEST=Compile and flash "rollback" test on dragontalon with region 0 On console: "runtest" => Reboots with "Data access violation, mfar = 80c0000" => PASS TEST=Compile and flash "rollback" test on dragontalon with region 1 On console: "runtest" => Reboots with "Data access violation, mfar = 80e0000" => PASS Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I748b7ea0654dee01d27bb560e82491665025d1ef Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2200200 Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Yicheng Li <yichengli@chromium.org> Tested-by: Yicheng Li <yichengli@chromium.org>
Diffstat (limited to 'core')
-rw-r--r--core/cortex-m/mpu.c55
1 files changed, 51 insertions, 4 deletions
diff --git a/core/cortex-m/mpu.c b/core/cortex-m/mpu.c
index 5ee92b4087..f16e6ca0da 100644
--- a/core/cortex-m/mpu.c
+++ b/core/cortex-m/mpu.c
@@ -240,10 +240,57 @@ int mpu_lock_rw_flash(void)
#ifdef CONFIG_ROLLBACK_MPU_PROTECT
int mpu_lock_rollback(int lock)
{
- return mpu_config_region(REGION_ROLLBACK,
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_ROLLBACK_OFF,
- CONFIG_ROLLBACK_SIZE, MPU_ATTR_XN | MPU_ATTR_NO_NO,
- lock);
+ int rv;
+ int num_mpu_regions = mpu_num_regions();
+
+ const uint32_t rollback_region_start_address =
+ CONFIG_MAPPED_STORAGE_BASE + CONFIG_ROLLBACK_OFF;
+ const uint32_t rollback_region_total_size = CONFIG_ROLLBACK_SIZE;
+ const uint16_t mpu_attr =
+ MPU_ATTR_XN /* Execute never */ |
+ MPU_ATTR_NO_NO /* No access (privileged or unprivileged */;
+
+ /*
+ * Originally rollback MPU support was added on Cortex-M7, which
+ * supports 16 MPU regions and has rollback region aligned in a way
+ * that we can use a single region.
+ */
+ uint8_t rollback_mpu_region = REGION_ROLLBACK;
+
+ if (rollback_mpu_region < num_mpu_regions) {
+ rv = mpu_config_region(rollback_mpu_region,
+ rollback_region_start_address,
+ rollback_region_total_size, mpu_attr,
+ lock);
+ return rv;
+ }
+
+ /*
+ * If we get here, we can't use REGION_ROLLBACK because our MPU doesn't
+ * have enough regions. Instead, we choose unused MPU regions.
+ *
+ * Note that on the Cortex-M3, Cortex-M4, and Cortex-M7, the base
+ * address used for an MPU region must be aligned to the size of the
+ * region, so it's not possible to use a single region to protect the
+ * entire rollback flash on the STM32F412 (bloonchipper); we have to
+ * use two.
+ *
+ * See mpu_update_region for alignment details.
+ */
+
+ rollback_mpu_region = REGION_CHIP_RESERVED;
+ rv = mpu_config_region(rollback_mpu_region,
+ rollback_region_start_address,
+ rollback_region_total_size / 2, mpu_attr, lock);
+ if (rv != EC_SUCCESS)
+ return rv;
+
+ rollback_mpu_region = REGION_STORAGE2;
+ rv = mpu_config_region(rollback_mpu_region,
+ rollback_region_start_address +
+ (rollback_region_total_size / 2),
+ rollback_region_total_size / 2, mpu_attr, lock);
+ return rv;
}
#endif