apache / apache/nuttx

armv7-m/arm_mpu.c: MPU regions >= 2GB cannot be configured

Open
#12,734 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
4k
Forks
1.7k
Avg merge
1d 17h
Merged PRs (30d)
237

Description

Hi, minor bug to report regarding the MPU configuration in armv7-m:

The cortex-M7 MPU supports configuring regions up to 4GB in size (_see ARMv7-M Arch. Reference Manual, System Address Map :: B3.5 Protected Memory System Architecture_). ([Download link here](https://developer.arm.com/documentation/ddi0403/latest/))

![image](https://github.com/user-attachments/assets/e620ea50-a8ab-40df-a463-637c4f82493c)

In [arm_mpu.c](https://github.com/apache/nuttx/blob/master/arch/arm/src/armv7-m/arm_mpu.c#L369), say you want to configure a 2 GiB sized region 2GiB offset from address 0:
```c
const size_t SIZE_2_GiB = 2 * 1024 * 1024 *1024; /* 0x80000000 */
mpu_configure_region(/*base = */ SIZE_2_GiB,
/*size = */ SIZE_2_GiB,
/*flags =*/ );

```
When we make it to the `DEBUG_ASSERT`s in the function, we'll have:

```c
l2size = 31;
alignedbase = SIZE_2_GiB;
```
The first assert, `DEBUGASSERT(alignedbase + (1 << l2size) >= base + size);`,
will expand to `DEBUGASSERT( 0 >= 0)` (due to unsigned integer overflow) and pass. The second assert, however,

```c
DEBUGASSERT(l2size == 5 ||
alignedbase + (1 << (l2size - 1)) < base + size);
```
will expand to

```c
DEBUGASSERT(false ||
SIZE_2_GiB + (1 << (30)) < 0);
```

and fail because only the right-hand-side will overflow. The workaround for this would be:
- saying we only allow regions of 1GiB max size to be configured,
- using uint64_t for our arguments and arithmetic in this entire file,
- just have a special case where values for `base` and `size` >= 2GiB are handled differently, or
- just telling users to program the MPU registers directly themselves rather than relying on this convenience function

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.