• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
4 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
5 */
6
7#include <linux/linkage.h>
8#include <asm/vfpmacros.h>
9
10	.text
11	.pushsection	.hyp.text, "ax"
12
13/* void __vfp_save_state(struct vfp_hard_struct *vfp); */
14ENTRY(__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
331:
34	VFPFSTMIA r0, r5		@ Save VFP registers
35	stm	r0, {r1-r4}		@ Save FPEXC, FPSCR, FPINST, FPINST2
36	pop	{r4, r5}
37	bx	lr
38ENDPROC(__vfp_save_state)
39
40/* void __vfp_restore_state(struct vfp_hard_struct *vfp);
41 * Assume FPEXC_EN is on and FPEXC_EX is off */
42ENTRY(__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
521:
53	VFPFMXR FPEXC, r0		@ FPEXC	(last, in case !EN)
54	bx	lr
55ENDPROC(__vfp_restore_state)
56
57	.popsection
58