You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/02/19 13:28:34 UTC
[incubator-nuttx] 02/02: armv7-m: Ensure RBAR alignment
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch pr304
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 942fa2286b06a519a1c637b43e1a9fe7524357cd
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Wed Feb 19 16:49:22 2020 +0900
armv7-m: Ensure RBAR alignment
Fix crashes on init task startup I observed on
qemu-system-arm -M lm3s6965evb.
---
arch/arm/src/armv7-m/mpu.h | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/arm/src/armv7-m/mpu.h b/arch/arm/src/armv7-m/mpu.h
index bcc3c0c..0a5c4de 100644
--- a/arch/arm/src/armv7-m/mpu.h
+++ b/arch/arm/src/armv7-m/mpu.h
@@ -282,6 +282,23 @@ static inline void mpu_configure_region(uintptr_t base, size_t size,
uint32_t regval;
uint8_t l2size;
uint8_t subregions;
+ uintptr_t alignedbase;
+
+ /* Ensure the base address alignment
+ *
+ * ARMv7-M Architecture Reference Manual
+ * B3.5.8 MPU Region Base Address Register, MPU_RBAR
+ * "Software must ensure that the value written to the ADDR field
+ * aligns with the size of the selected region."
+ */
+ alignedbase = base & MPU_RBAR_ADDR_MASK;
+ l2size = mpu_log2regionceil(size + base - alignedbase);
+ alignedbase &= ~((1 << l2size) - 1);
+ l2size = mpu_log2regionceil(size + base - alignedbase);
+ DEBUGASSERT(alignedbase + (1 << l2size) >= base + size);
+ DEBUGASSERT(l2size == 5 || alignedbase + (1 << (l2size - 1)) < base + size);
+ DEBUGASSERT((alignedbase & MPU_RBAR_ADDR_MASK) == alignedbase);
+ DEBUGASSERT((alignedbase & ((1 << l2size) - 1)) == 0);
/* Select the region */
@@ -289,11 +306,10 @@ static inline void mpu_configure_region(uintptr_t base, size_t size,
/* Select the region base address */
- putreg32((base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID, MPU_RBAR);
+ putreg32(alignedbase | region | MPU_RBAR_VALID, MPU_RBAR);
/* Select the region size and the sub-region map */
- l2size = mpu_log2regionceil(size);
subregions = mpu_subregion(base, size, l2size);
/* The configure the region */