diff options
author | Tom Hughes <tomhughes@chromium.org> | 2020-05-13 15:20:08 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-22 03:31:56 +0000 |
commit | 288e1a5d8ea9be1e15829067969cc786d725a4a4 (patch) | |
tree | fef788b8b875b8fef2760bb5e04f6a0896f67ead /core | |
parent | 092918a531ec535a12db6bdf01af3d1b782630f5 (diff) | |
download | chrome-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')
-rw-r--r-- | core/cortex-m/include/mpu.h | 4 | ||||
-rw-r--r-- | core/cortex-m/mpu.c | 77 |
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; } |