The next generation of ARM Cortex-M processors will be powered by a new architecture version called ARMv8-M architecture. This document provides a technical overview of various enhancements in the new architecture, as well as an introduction to the security technology, called TrustZone for ARMv8-M. This document also introduces AMBA 5 AHB5 which enables security management at a system level, and covers various use cases of the new technology.
Introduction to the ARMv8‑M Architecture
TrustZone technology for ARMv8‑M Architecture
ARM C Language Extension (ACLE)
ACLE Extensions for ARMv8‑M
Secure software guidelines for ARMv8‑M based platforms
System Design for ARMv8-M
Exceptions and Interrupts
ARMv8‑M Exception Handling
Fault Handling and Detection
Power management and sleep modes
ARMv8-M processor power management secure state protection
ARMv8‑M Processor Debug
Memory Protection Unit for ARMv8‑M based platforms
RTOS design considerations for ARMv8‑M based platforms
ARMv8-M software development with ARM Compiler 6
Chapter 9 : Building Secure and Non-secure Images Using ARMv8-M Security Extensions
TrustZone software development in Keil MDK
Keil Application Note 291: Using TrustZone on ARMv8-M
Security extension details for compiler vendors
ARMv8-M Security Extension: Requirements on Development Tools
ARMv8-M software development
EW2017 - Software Development on ARMv8-M Arhcitecture
mbed(TM)OS deployment on Armv8-M
EW2017 - High-End Security Features for Low-End Microcontrollers
EW2019 - How RTOS should work in a TrustZone for Armv8-M environment
TrustZone Secure software
Stack sealing and why it is needed in TrustZone for Armv8-M
Hello Joseph Yiu,
thank you very much for the detailed explanations.
I understood well.
Sorry for the delay of my reply, I am travelling in Asia (holiday) at the moment.
Lazy stacking feature is enabled by default, and is controlled by FPCCR.LSPEN (no change from Cortex-M4).
Software can switch it off if it need to.
The challenging part would be what is being pushed to the stack:
- R0-R3, R12, LR, PC, xPSR : always push to the stack in exception entry
- S0-S15, FPSCR : stack frame always allocate the space for them if FPU is enabled and floating point context is active (CONTROL.FPCA==1), but the push might be deferred by lazy stacking.
- R4-R11 : push to Secure stack if Non-secure exception occurred running Secure code execution.
- S16-S31: stack frame allocate space for them if Non-secure exception occurred running Secure code execution, and FPCCR_S.TS is 1, and FPU enabled and is active (CONTROL.FPCA=1), but the push might be deferred by lazy stacking.
Hope this helps.
I am not exactly sure what you mean. The state of the stack after an exception for various combinations of secure and non-secure state or floating point are shown in section B4.20 of the ARMv8-M Architecture Reference manual
Lazy stacking only applies to the floating point registers. If an exception occurs in secure state taking it to a non-secure state then all the general registers are saved and zeroed, and then restored on return to secure state.
Hello daith ,
thank you for your detailed reply.
I understood your comments as that the FPU lazy stacking was always enabled, and the stacking (if needed) would be done as the normal general registers. Also in the case of change from Secure to Non-Secure world, all the regsisters would be cleared.
Is my understanding correct?
That statement in the Overview is more a description about the intent and effect rather than anything about the mechanism. The ARMv8-M Architecture Reference Manual goes into more detail - and the bits about what happens to the floating point registers with lazy stacking do not make for easy reading.
As far as I can make out and assuming the secure state has used floating point then on a non-secure interrupt with lazy stacking enabled:-
Space is left on the secure stack for all the floating point registers, not just s0-s15 and a lazy saving state bit is set and a bit saying the floating point has been used cleared.
The interrupt routine is entered
If the interrupt routine does not use floating point then on return the floating point registers need never have been saved and they are certainly not restored - the bits will be set saying lazy saving not in use and floating point registers have been used just like it was before the interrupt.
if the interrupt routine uses floating point then the processor will ensure that all the registers are saved on the secure stack and the lazy saving state ended and mark that floating point registers have been used. All the floating point registers will be zeroed before first use in the interrupt.. On return it will see that floating point has been used and will restore the floating point registers from the stack.
The strong imperative they had was to ensure floating point use in secure state does not slow down interrupts which don't use floating point What they came up with should be easy to use and ensure security by not leaking floating point register values - it is most certainly not trivial though and I bet they've had to really sweat over checking it all out..