Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hal/armv7m: allow for more granular memory maps #365

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jmaksymowicz
Copy link
Contributor

@jmaksymowicz jmaksymowicz commented Oct 22, 2024

Use MPU region overlap feature to allow for more granularity when translating memory maps to MPU regions.

Description

On armv7m, the MPU only supports regions if their size is a power of 2 and they are aligned to their size. Additionally, each region is divided into 8 equally sized subregions which can be enabled individually. Memory maps passed using map command must be translated into one or more MPU regions so that memory protection can be enforced.

In practice this means that the start and end address representable with one region can have up to 3 "significant bits" - for example, an address range 0x20000 - 0x20500 can be represented with a single region, but range 0x20000 - 0x20900 requires 2 regions. Currently our code will limit assigning regions to 2 per map, which means that attempting to create a more granular memory map will fail.

To work around this without creating excessively many regions, the new code uses the fact that armv7m MPU supports overlapping regions. It detects how many regions would be necessary, if more than 2 the code will attempt to allocate a region larger than the memory map (rounded up to smallest representable region) then block off the excess using another memory region. This "blocking" region is set to not allow any access to the "blocked" memory. Due to the way priorities work, any subsequent mapping that overlaps this "blocking" region will take precedence.

However, if a "blocking" region were to overlap an existing region, it would take precedence and MPU will not allow access even if a program is allowed access to both memory maps. To prevent this unintuitive behavior, the code checks for this situation and fails the map command. This has a side effect that now the order in which map commands are issued may affect their success or failure. This isn't optimal, but thanks to failing early these situations would be easy to detect and fix.

For example: based on the following memory maps

map dtcm 0x20000000 0x2003f000 rwcb
map rtt 0x2003f000 0x20040000 rw

the new code will create MPU regions

MAP NAME  REGION  SUB  START       END         EN  XN  PERM P/U  TEX  S  C  B
dtcm      1       all  0x20000000  0x2003ffff  y   y   rw/rw     000  n  y  y
dtcm      2       all  0x2003f000  0x2003ffff  y   n   na/na     000  n  n  n
rtt       3       all  0x2003f000  0x2003ffff  y   y   rw/rw     000  n  n  n

Motivation and Context

For using RTT a memory map needs to be created, which most likely means cutting out a part of an existing memory map. This PR allows the "cutout" to be as small as possible.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: imxrt117x

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

hal/armv7m/mpu.c Outdated Show resolved Hide resolved
hal/armv7m/mpu.c Outdated Show resolved Hide resolved
hal/armv7m/mpu.c Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Oct 22, 2024

Unit Test Results

7 787 tests  ±0   7 069 ✅ ±0   40m 57s ⏱️ - 1m 44s
  461 suites ±0     718 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit e42ae37. ± Comparison against base commit 0f947dc.

♻️ This comment has been updated with latest results.

Use MPU region overlap feature to allow for more granularity when
translating memory maps to MPU regions.
With this feature, the code can now create an MPU region larger than the
map, then "mask off" the excess with another region.

Improve MPU region code to handle more edge cases.
Replace inline assembly with builtins for `ctz` function.

JIRA: RTOS-950
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant