1
2
3
4
5
6
7 #include <linux/linkage.h>
8 #include <asm/vfpmacros.h>
9
10 .text
11 .pushsection .hyp.text, "ax"
12
13
14 ENTRY(__vfp_save_state)
15 push {r4, r5}
16 VFPFMRX r1, FPEXC
17
18 @ Make sure *really* VFP is enabled so we can touch the registers.
19 orr r5, r1, #FPEXC_EN
20 tst r5, #FPEXC_EX @ Check for VFP Subarchitecture
21 bic r5, r5, #FPEXC_EX @ FPEXC_EX disable
22 VFPFMXR FPEXC, r5
23 isb
24
25 VFPFMRX r2, FPSCR
26 beq 1f
27
28 @ If FPEXC_EX is 0, then FPINST/FPINST2 reads are upredictable, so
29 @ we only need to save them if FPEXC_EX is set.
30 VFPFMRX r3, FPINST
31 tst r5, #FPEXC_FP2V
32 VFPFMRX r4, FPINST2, ne @ vmrsne
33 1:
34 VFPFSTMIA r0, r5 @ Save VFP registers
35 stm r0, {r1-r4} @ Save FPEXC, FPSCR, FPINST, FPINST2
36 pop {r4, r5}
37 bx lr
38 ENDPROC(__vfp_save_state)
39
40
41
42 ENTRY(__vfp_restore_state)
43 VFPFLDMIA r0, r1 @ Load VFP registers
44 ldm r0, {r0-r3} @ Load FPEXC, FPSCR, FPINST, FPINST2
45
46 VFPFMXR FPSCR, r1
47 tst r0, #FPEXC_EX @ Check for VFP Subarchitecture
48 beq 1f
49 VFPFMXR FPINST, r2
50 tst r0, #FPEXC_FP2V
51 VFPFMXR FPINST2, r3, ne
52 1:
53 VFPFMXR FPEXC, r0 @ FPEXC (last, in case !EN)
54 bx lr
55 ENDPROC(__vfp_restore_state)
56
57 .popsection