Skip to content

Commit adfedcc

Browse files
committed
Fix a number of issues in CMSE examples
- Use CLRM to clear registers instead of a sequence of mov rX, #0. - Save and restore FPCXTS in transitions from Secure to Non-secure and vice-versa. - Use VSCCLRM to clear floating-point registers if necessary.
1 parent 9e4c66a commit adfedcc

File tree

2 files changed

+41
-63
lines changed

2 files changed

+41
-63
lines changed

cmse/cmse.md

Lines changed: 40 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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
11781184
You 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
12711278
A toolchain could provide you with the means to specify that some
12721279
types 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
12881295
The 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
12911298
An 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

main/acle.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,12 +341,7 @@ Armv8.4-A [[ARMARMv84]](#ARMARMv84). Support is added for the Dot Product intrin
341341
* Fixes for [Function Multi Versioning](#function-multi-versioning):
342342
* Renamed features to `sme-f64f64` and `sme-i16i64`
343343
* Corrected register name to `ID_AA64SMFR0_EL1.I16I64`
344-
* Removed incorrect optimisation remark in [CMSE](#CMSE-ACLE)'s floating-point
345-
register clearing.
346-
* Removed incorrect information about the floating-point ABI used in
347-
[CMSE](#CMSE-ACLE)'s Arguments on the stack and floating point handling.
348-
* Corrected description and example in [CMSE](#CMSE-ACLE)'s section about
349-
non-secure function pointers.
344+
* Several fixes in [CMSE](#CMSE-ACLE).
350345

351346
### References
352347

0 commit comments

Comments
 (0)