Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[cascardo/linux.git] / arch / arm / kvm / hyp / vfp.S
1 /*
2  * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3  * Author: Christoffer Dall <c.dall@virtualopensystems.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <linux/linkage.h>
19 #include <asm/vfpmacros.h>
20
21         .text
22         .pushsection    .hyp.text, "ax"
23
24 /* void __vfp_save_state(struct vfp_hard_struct *vfp); */
25 ENTRY(__vfp_save_state)
26         push    {r4, r5}
27         VFPFMRX r1, FPEXC
28
29         @ Make sure *really* VFP is enabled so we can touch the registers.
30         orr     r5, r1, #FPEXC_EN
31         tst     r5, #FPEXC_EX           @ Check for VFP Subarchitecture
32         bic     r5, r5, #FPEXC_EX       @ FPEXC_EX disable
33         VFPFMXR FPEXC, r5
34         isb
35
36         VFPFMRX r2, FPSCR
37         beq     1f
38
39         @ If FPEXC_EX is 0, then FPINST/FPINST2 reads are upredictable, so
40         @ we only need to save them if FPEXC_EX is set.
41         VFPFMRX r3, FPINST
42         tst     r5, #FPEXC_FP2V
43         VFPFMRX r4, FPINST2, ne         @ vmrsne
44 1:
45         VFPFSTMIA r0, r5                @ Save VFP registers
46         stm     r0, {r1-r4}             @ Save FPEXC, FPSCR, FPINST, FPINST2
47         pop     {r4, r5}
48         bx      lr
49 ENDPROC(__vfp_save_state)
50
51 /* void __vfp_restore_state(struct vfp_hard_struct *vfp);
52  * Assume FPEXC_EN is on and FPEXC_EX is off */
53 ENTRY(__vfp_restore_state)
54         VFPFLDMIA r0, r1                @ Load VFP registers
55         ldm     r0, {r0-r3}             @ Load FPEXC, FPSCR, FPINST, FPINST2
56
57         VFPFMXR FPSCR, r1
58         tst     r0, #FPEXC_EX           @ Check for VFP Subarchitecture
59         beq     1f
60         VFPFMXR FPINST, r2
61         tst     r0, #FPEXC_FP2V
62         VFPFMXR FPINST2, r3, ne
63 1:
64         VFPFMXR FPEXC, r0               @ FPEXC (last, in case !EN)
65         bx      lr
66 ENDPROC(__vfp_restore_state)
67
68         .popsection