summaryrefslogtreecommitdiff
path: root/core/cortex-m
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2020-05-13 15:20:08 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-22 03:31:56 +0000
commit288e1a5d8ea9be1e15829067969cc786d725a4a4 (patch)
treefef788b8b875b8fef2760bb5e04f6a0896f67ead /core/cortex-m
parent092918a531ec535a12db6bdf01af3d1b782630f5 (diff)
downloadchrome-ec-288e1a5d8ea9be1e15829067969cc786d725a4a4.tar.gz
cortex-m: Clean up MPU logic
Add error checking for failures and use IS_ENABLED combined with helper functions for readability. 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" => Memory is successfully read => FAIL 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" 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: I0f8d149c8c5c568241457a6779079c65eb38ce32 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2200199 Commit-Queue: Jett Rink <jettrink@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'core/cortex-m')
-rw-r--r--core/cortex-m/include/mpu.h4
-rw-r--r--core/cortex-m/mpu.c77
2 files changed, 63 insertions, 18 deletions
diff --git a/core/cortex-m/include/mpu.h b/core/cortex-m/include/mpu.h
index 62e9b8bbec..17539fa09e 100644
--- a/core/cortex-m/include/mpu.h
+++ b/core/cortex-m/include/mpu.h
@@ -42,6 +42,10 @@ enum mpu_region {
#define MPU_SIZE REG16(0xe000eda0)
#define MPU_ATTR REG16(0xe000eda2)
+/*
+ * See ARM v7-M Architecture Reference Manual
+ * Section B3.5.5 MPU Type Register, MPU_TYPE
+ */
#define MPU_TYPE_UNIFIED_MASK 0x00FF0001
#define MPU_TYPE_REG_COUNT(t) (((t) >> 8) & 0xFF)
diff --git a/core/cortex-m/mpu.c b/core/cortex-m/mpu.c
index fa6efb5951..5ee92b4087 100644
--- a/core/cortex-m/mpu.c
+++ b/core/cortex-m/mpu.c
@@ -13,6 +13,32 @@
#include "util.h"
/**
+ * @return Number of regions supported by the MPU. 0 means the processor does
+ * not implement an MPU.
+ */
+int mpu_num_regions(void)
+{
+ return MPU_TYPE_REG_COUNT(mpu_get_type());
+}
+
+/**
+ * @return true if processor has MPU, false otherwise
+ */
+bool has_mpu(void)
+{
+ return mpu_num_regions() != 0;
+}
+
+/**
+ * @return true if MPU has unified instruction and data maps, false otherwise
+ */
+bool mpu_is_unified(void)
+{
+ return (mpu_get_type() & MPU_TYPE_UNIFIED_MASK) == 0;
+}
+
+
+/**
* Update a memory region.
*
* region: index of the region to update
@@ -235,32 +261,47 @@ int mpu_lock_rollback(int lock)
int mpu_pre_init(void)
{
int i;
- uint32_t mpu_type = mpu_get_type();
+ int num_mpu_regions;
+ int rv;
+
+ if (!has_mpu())
+ return EC_ERROR_HW_INTERNAL;
+
+ num_mpu_regions = mpu_num_regions();
/* Supports MPU with 8 or 16 unified regions */
- if ((mpu_type & MPU_TYPE_UNIFIED_MASK) ||
- (MPU_TYPE_REG_COUNT(mpu_type) != 8 &&
- MPU_TYPE_REG_COUNT(mpu_type) != 16))
+ if (!mpu_is_unified() ||
+ (num_mpu_regions != 8 && num_mpu_regions != 16))
return EC_ERROR_UNIMPLEMENTED;
mpu_disable();
- for (i = 0; i < MPU_TYPE_REG_COUNT(mpu_type); ++i)
- mpu_config_region(i, CONFIG_RAM_BASE, CONFIG_RAM_SIZE, 0, 0);
+ for (i = 0; i < num_mpu_regions; ++i) {
+ rv = mpu_config_region(i, CONFIG_RAM_BASE, CONFIG_RAM_SIZE, 0,
+ 0);
+ if (rv != EC_SUCCESS)
+ return rv;
+ }
-#ifdef CONFIG_ROLLBACK_MPU_PROTECT
- mpu_lock_rollback(1);
-#endif
+ if (IS_ENABLED(CONFIG_ROLLBACK_MPU_PROTECT)) {
+ rv = mpu_lock_rollback(1);
+ if (rv != EC_SUCCESS)
+ return rv;
+ }
-#ifdef CONFIG_ARMV7M_CACHE
+ if (IS_ENABLED(CONFIG_ARMV7M_CACHE)) {
#ifdef CONFIG_CHIP_UNCACHED_REGION
- mpu_config_region(REGION_UNCACHED_RAM,
- CONCAT2(_region_start_, CONFIG_CHIP_UNCACHED_REGION),
- CONCAT2(_region_size_, CONFIG_CHIP_UNCACHED_REGION),
- MPU_ATTR_XN | MPU_ATTR_RW_RW, 1);
- mpu_enable();
-#endif /* CONFIG_CHIP_UNCACHED_REGION */
- cpu_enable_caches();
-#endif /* CONFIG_ARMV7M_CACHE */
+ rv = mpu_config_region(
+ REGION_UNCACHED_RAM,
+ CONCAT2(_region_start_, CONFIG_CHIP_UNCACHED_REGION),
+ CONCAT2(_region_size_, CONFIG_CHIP_UNCACHED_REGION),
+ MPU_ATTR_XN | MPU_ATTR_RW_RW, 1);
+ if (rv != EC_SUCCESS)
+ return rv;
+
+ mpu_enable();
+#endif
+ cpu_enable_caches();
+ }
return EC_SUCCESS;
}