diff options
author | Tom Hughes <tomhughes@chromium.org> | 2020-05-13 15:22:48 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-22 19:21:55 +0000 |
commit | 38df3878f8d7d4bc149faaa0884f0ded501b491c (patch) | |
tree | f6d24b5542e88464a9844885951ae036293d11da | |
parent | 43c2f29347bc0e98ef877afb720977d594461473 (diff) | |
download | chrome-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>
-rw-r--r-- | core/cortex-m/mpu.c | 55 |
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 |