diff --git a/arch/arm/src/armv7-m/mpu.h b/arch/arm/src/armv7-m/mpu.h index 4a5bab065b..5017023c66 100644 --- a/arch/arm/src/armv7-m/mpu.h +++ b/arch/arm/src/armv7-m/mpu.h @@ -170,11 +170,11 @@ unsigned int mpu_allocregion(void); * Determine the smallest value of l2size (log base 2 size) such that the * following is true: * - * size <= (1 << l2size) + * (base & ((1 << l2size) - 1)) + size <= (1 << l2size) * ****************************************************************************/ -uint8_t mpu_log2regionceil(size_t size); +uint8_t mpu_log2regionceil(uintptr_t base, size_t size); /**************************************************************************** * Name: mpu_log2regionfloor @@ -183,11 +183,11 @@ uint8_t mpu_log2regionceil(size_t size); * Determine the largest value of l2size (log base 2 size) such that the * following is true: * - * size >= (1 << l2size) + * (base & ((1 << l2size) - 1)) + size >= (1 << l2size) * ****************************************************************************/ -uint8_t mpu_log2regionfloor(size_t size); +uint8_t mpu_log2regionfloor(uintptr_t base, size_t size); /**************************************************************************** * Name: mpu_subregion @@ -286,7 +286,7 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -327,7 +327,7 @@ static inline void mpu_user_flash(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -365,7 +365,7 @@ static inline void mpu_priv_flash(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -403,7 +403,7 @@ static inline void mpu_user_intsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -442,7 +442,7 @@ static inline void mpu_priv_intsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -481,7 +481,7 @@ static inline void mpu_user_extsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -521,7 +521,7 @@ static inline void mpu_priv_extsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -561,7 +561,7 @@ static inline void mpu_peripheral(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ - l2size = mpu_log2regionceil(size); + l2size = mpu_log2regionceil(base, size); subregions = mpu_subregion(base, size, l2size); /* Then configure the region */ diff --git a/arch/arm/src/armv7-m/up_mpu.c b/arch/arm/src/armv7-m/up_mpu.c index 3e802fddfd..9370f2108d 100644 --- a/arch/arm/src/armv7-m/up_mpu.c +++ b/arch/arm/src/armv7-m/up_mpu.c @@ -221,17 +221,24 @@ unsigned int mpu_allocregion(void) * Determine the smallest value of l2size (log base 2 size) such that the * following is true: * - * size <= (1 << l2size) + * (base & ((1 << l2size) - 1)) + size <= (1 << l2size) * ****************************************************************************/ -uint8_t mpu_log2regionceil(size_t size) +uint8_t mpu_log2regionceil(uintptr_t base, size_t size) { uint8_t l2size; /* The minimum permitted region size is 32 bytes (log2(32) = 5. */ - for (l2size = 5; l2size < 32 && size > (1 << l2size); l2size++); + for (l2size = 5; l2size < 32; l2size++) + { + if ((base & ((1 << l2size) - 1)) + size <= (1 << l2size)) + { + break; + } + } + return l2size; } @@ -242,15 +249,15 @@ uint8_t mpu_log2regionceil(size_t size) * Determine the largest value of l2size (log base 2 size) such that the * following is true: * - * size >= (1 << l2size) + * (base & ((1 << l2size) - 1)) + size >= (1 << l2size) * ****************************************************************************/ -uint8_t mpu_log2regionfloor(size_t size) +uint8_t mpu_log2regionfloor(uintptr_t base, size_t size) { - uint8_t l2size = mpu_log2regionceil(size); + uint8_t l2size = mpu_log2regionceil(base, size); - if (l2size > 4 && size < (1 << l2size)) + if (l2size > 4 && (base & ((1 << l2size) - 1)) + size < (1 << l2size)) { l2size--; }