@@ -160,8 +160,13 @@ Anticipated changes to this document include:
160160 [ Arguments on the stack and floating point handling] ( #arguments-on-the-stack-and-floating-point-handling ) .
161161* Removed incorrect information about the floating-point ABI used in
162162 [ Arguments on the stack and floating point handling] ( #arguments-on-the-stack-and-floating-point-handling ) .
163+ * Replaced a conditional clearing of floating-point registers by the ` VSCCLRM `
164+ instruction in the example in
165+ [ Arguments on the stack and floating point handling] ( #arguments-on-the-stack-and-floating-point-handling ) .
163166* Corrected description and example in section
164167 [ Non-secure function pointers] ( #non-secure-function-pointer ) .
168+ * Corrected examples to save and restore ` FPCXT ` in Security state transitions.
169+ * Replaced sequences of ` mov rX, #0 ` by the ` CLRM ` instruction in examples.
165170
166171## References
167172
@@ -1173,7 +1178,8 @@ registers that contain secret information
11731178> * Clear all registers and flags that have undefined values at the return of a
11741179> procedure, according to [[AAPCS]](#AAPCS).
11751180> * Restore all callee-saved registers as mandated by [[AAPCS]](#AAPCS).
1176- > * Restore bits [27:0] of FPSCR (Armv8.1-M Mainline only).
1181+ > * Restore the Non-secure Floating-point context payload (`FPCXTNS`)
1182+ > (Armv8.1-M Mainline only).
11771183
11781184You can clear the floating-point registers conditionally by checking the
11791185`SFPA` bit of the special-purpose `CONTROL` register.
@@ -1266,16 +1272,17 @@ the non-secure state to restore these registers.
12661272> * Registers that do not hold secret information.
12671273> * Clear all registers and flags that have undefined values at the entry to a
12681274> procedure according to the [[AAPCS]](#AAPCS).
1269- > * Save and clear bits [27:0] of FPSCR (Armv8.1-M Mainline only).
1275+ > * Save and clear the Secure Floating-point context payload (`FPCXTS`)
1276+ > (Armv8.1-M Mainline only).
12701277
12711278A toolchain could provide you with the means to specify that some
12721279types of variables never hold secret information.
12731280
12741281<span id="requirement-54" class="requirement-box"></span>
12751282
12761283> When the non-secure function call returns, caller- and callee-saved
1277- > registers saved before the call must be restored. This includes bits [27:0]
1278- > of FPSCR (Armv8.1-M Mainline only).
1284+ > registers saved before the call must be restored. This includes `FPCXTS`
1285+ > (Armv8.1-M Mainline only).
12791286> An implementation need not save and restore a register if its value is not
12801287> live across the call. Note: callee-saved registers are live across the
12811288> call in almost all situations. These requirements specify behaviour that is
@@ -1286,7 +1293,7 @@ types of variables never hold secret information.
12861293> must be cleared.
12871294
12881295The floating point registers can very efficiently be saved and cleared using
1289- the `VLSTM`, and restored using `VLLDM` instructions.
1296+ the `VLSTM`, and restored using `VLLDM` instructions. These include `FPCXTS`.
12901297
12911298An example instruction sequence for a non-secure call is listed in
12921299[Example non-secure function call](#example-non-secure-function-call).
@@ -1595,12 +1602,8 @@ bar:
15951602 @ save callee-saved integer registers
15961603 push {r4-r12, lr}
15971604 @ clear all integer registers (except for function pointer and arguments)
1598- mov r2, #0
1599- mov r3, #0
1600- …
1601- mov r12, #0
1602- @ clear the integer status flags
1603- msr APSR_nzcvqg, r2
1605+ @ and the integer status flags
1606+ clrm {r2-r12, apsr}
16041607 @ perform the call to the non-secure function
16051608 bic r1, r1, #1
16061609 blxns r1
@@ -1642,12 +1645,8 @@ bar:
16421645 @ setup floating point arguments of the call
16431646 vmov s0, r1
16441647 @ clear all integer registers (except for function pointer and arguments)
1645- mov r2, #0
1646- mov r3, #0
1647- …
1648- mov r12, #0
1649- @ clear the integer status flags
1650- msr APSR_nzcvqg, r2
1648+ @ and the integer status flags
1649+ clrm {r2-r12, apsr}
16511650 @ perform the call to the non-secure function
16521651 bic r0, r0, #1
16531652 blxns r0
@@ -1723,12 +1722,8 @@ bar:
17231722 @ load the function pointer
17241723 ldr r4, =foo
17251724 @ clear all integer registers (except for function pointer and arguments)
1726- mov r6, #0
1727- mov r7, #0
1728- …
1729- mov r12, #0
1730- @ clear the integer status flags
1731- msr APSR_nzcvqg, r6
1725+ @ and the integer status flags
1726+ clrm {r6-r12, apsr}
17321727 @ perform the call to the non-secure function
17331728 bic r4, r4, #1
17341729 blxns r4
@@ -1810,65 +1805,53 @@ __acle_se_foo:
18101805 tst lr, #1
18111806 it eq
18121807 subeq sp, sp, #8
1813- @ 2: push used callee-saved register onto the stack
1808+ @ 2: save Non-secure Floating-point context payload
1809+ vstr fpcxtns, [sp, #-8]!
1810+ @ 3: push used callee-saved register onto the stack
18141811 push {r4-r6, lr}
1815- @ 3: if called from secure the arguments are already in the correct place
1816- tst lr, #1
1812+ @ 4: if called from secure the arguments are already in the correct place
18171813 bne .LdoneARGS
1818- @ 4 : get the non-secure stack pointer
1814+ @ 5 : get the non-secure stack pointer
18191815 mrs r4, SP_NS
1820- @ 5 : calculate end of range
1816+ @ 6 : calculate end of range
18211817 adds r6, r4, #7
1822- @ 6 : take permissions at begin and end of range
1818+ @ 7 : take permissions at begin and end of range
18231819 tta r5, r4
18241820 tta r6, r6
1825- @ 7 : check if range is in one region (this means identical permissions)
1821+ @ 8 : check if range is in one region (this means identical permissions)
18261822 cmp r5, r6
18271823 it ne
18281824 blne cmse_abort
1829- @ 8 : check bit 20 of the TT result (non-secure read flag)
1825+ @ 9 : check bit 20 of the TT result (non-secure read flag)
18301826 tst r5, #0x100000
18311827 it eq
18321828 bleq cmse_abort
1833- @ 9 : copy arguments from non-secure stack to secure stack
1829+ @10 : copy arguments from non-secure stack to secure stack
18341830 ldr r5, [r4 ]
18351831 ldr r6, [r4, #4 ]
18361832 str r5, [sp, #16]
18371833 str r6, [sp, #20]
18381834.LdoneARGS:
1839- @10 : function body
1835+ @11 : function body
18401836 ldr r0, [sp, #16]
18411837 ldr r1, [sp, #20]
18421838 bl bar
1843- @11 : restore used callee-saved registers
1839+ @12 : restore used callee-saved registers
18441840 pop {r4-r6, lr}
1845- @12: if called from secure, we are done
1841+ @13: restore Non-secure Floating-point context payload
1842+ vldr fpcxtns, [sp], #8
1843+ @14: if called from secure, we are done
18461844 tst lr, #1
1847- it ne
18481845 bxne lr
1849- @13 : pop secure stack space
1846+ @15 : pop secure stack space
18501847 add sp, sp, #8
1851- @14: check SFPA bit to see if FP is used
1852- mrs r1, control
1853- tst r1, #8
1854- bne .LdoneFP
1855- @15: clear floating point caller-saved registers
1856- mov r1, #0
1857- vmov s0, s1, r1, r1
1858- vmov s2, s3, r1, r1
1859- ...
1860- vmov s30, s31, r1, r1
1861- @16: clear floating point flags
1862- vmsr fpscr, r1
1848+ @16: clear floating point caller-saved registers if a FP context is active
1849+ vscclrm {s0-s31}
18631850.LdoneFP:
1864- @17: clear integer caller-saved registers except for return value
1865- mov r1, #0
1866- mov r2, #0
1867- mov r3, #0
1868- @18: clear other registers and the integer status flags
1869- mov r12, #0
1870- msr APSR_nzcvqg, r3
1871- @19: return to non-secure state
1851+ @17: clear integer caller-saved registers except for return value,
1852+ @ r12 and the integer status flags
1853+ clrm {r1-r3, r12, apsr}
1854+ @18: return to non-secure state
18721855 bxns lr
18731856```
18741857
0 commit comments