hal/armv7m: allow for more granular memory maps #365
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 range0x20000 - 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 whichmap
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
the new code will create MPU regions
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
How Has This Been Tested?
Checklist:
Special treatment