All Freescale macros for memory access replaced #6
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.
tl;dr
Brace yourselves: This is a PR changing ~5k lines. Every Freescale macro containing direct memory accesses (
*addr = val
) has been replaced with a memory access macro (ADDRESS_WRITE(addr, val)
). In this way memory accesses can be centrally redefined for special requirements. A script was used, with the help of 18 regular expressions.Background
In uVisor we use ACLs to tell if a resource can be granted access to. Peripheral ACLs specify permission levels for whole peripheral slots, but some registers in those slots may still enforce higher restrictions. For example, RTC registers require superuser access unless a certain RTC-specific bit is set.
Accessing these registers might incur in a bus fault. uVisor is able to recover from bus faults, perform the r/w operation if an ACL covers it, and continue execution regularly, but this requires the memory access to be well defined, that is, parse-able.
The Problem
All functions in the Freescale K64F HAL ultimately use macros to perform r/w operations on peripheral registers. These macros have usually a structure like the following:
where
v
is the value to write to the bitBIT
in the registerREG
of the peripheralPERIPH
at the addressx
.BITBAND_ACCESS(x, n)
is a macro that de-references the aliased bitband address obtained fromx
andn
.With this style we are not able to centrally re-define different behaviours for memory accesses. Every single macro implements a memory access explicitly (
*addr = val
), which cannot be replaced by a uVisor counterpart.The Solution
The solution is to replace every direct access to memory in the header files with a macro that implements memory access indirectly, so that if uVisor is used it turns into a dedicated function, otherwise the straightforward pointer de-referencing is used.
This is done using a script,
uvisor_replace.py
, that scans header files using a total of 18 regular expressions. These capture all the combinations of possible macros, classified as follows:Why Do I Care?
If you only use Freescale K64F HAL functions (or higher level functions that call HAL functions) you are fine - this all happens under the hood. If, instead, you sometimes access registers or their bitfields singularly with a direct memory access then you have 3 options:
B{W,R}_PERIPH_REG_BIT(x, n, v)
(Freescale specific)ADDRESS_{READ,WRITE}{32,16,8}(addr(, val))
; theaddr
field can also be replaced by a bitband translation withBITBAND_ADDRESS{32,16,8}(addr, bit)
(uVisor specific)Changelog
mbed-hal-k64f/device/MK64F12/*.h
mbed-hal-k64f/device/MK64F12/fsl_bitaccess.h
with centralised memory access macrombed-hal-k64f/device/MK64F12/MK64F_sim_uvisor.h
, superseded by these changes