1
2/************************************************************************************
3 * Included Files
4 ************************************************************************************/
5#define __ASSEMBLY__
6#include "irq_ctx.h"
7
8#if defined(CONFIG_ARCH_FPU)
9/************************************************************************************
10 * Pre-processor Definitions
11 ************************************************************************************/
12
13/************************************************************************************
14 * Public Symbols
15 ************************************************************************************/
16
17	.globl		riscv_fpuconfig
18	.globl		riscv_savefpu
19	.globl		riscv_savefpu_force
20	.globl		riscv_restorefpu
21
22	.file		"riscv_fpu.S"
23
24#define FS_MASK		0x6000
25#define FS_OFF		0x0000
26#define FS_INITIAL	0x2000
27#define FS_CLEAN	0x4000
28#define FS_DIRTY	0x6000
29
30#if defined(CONFIG_ARCH_DPFPU)
31#  define FLOAD		fld
32#  define FSTORE	fsd
33#  define LOAD		ld
34#  define STORE		sd
35#elif defined(CONFIG_ARCH_QPFPU)
36#  define FLOAD		flq
37#  define FSTORE	fsq
38#else
39#  define FLOAD		flw
40#  define FSTORE	fsw
41#  define LOAD		lw
42#  define STORE		sw
43#endif
44
45/************************************************************************************
46 * Public Functions
47 ************************************************************************************/
48
49/************************************************************************************
50 * Name: riscv_fpuconfig
51 *
52 * Description:
53 *   init fpu
54 *
55 * C Function Prototype:
56 *   void riscv_fpuconfig(void);
57 *
58 * Input Parameters:
59 *   None
60 *
61 * Returned Value:
62 *   This function does not return anything explicitly.
63 *
64 ************************************************************************************/
65
66	.type		riscv_fpuconfig, function
67
68riscv_fpuconfig:
69	li			a0, FS_INITIAL
70	csrs		mstatus, a0
71	csrwi		fcsr, 0
72	ret
73
74/************************************************************************************
75 * Name: riscv_savefpu
76 *
77 * Description:
78 *   Given the pointer to a register save area (in A0), save the state of the
79 *   floating point registers.
80 *
81 * C Function Prototype:
82 *   void riscv_savefpu(uintptr_t *regs);
83 *
84 * Input Parameters:
85 *   regs - A pointer to the register save area in which to save the floating point
86 *     registers
87 *
88 * Returned Value:
89 *   None
90 *
91 ************************************************************************************/
92
93	.type		riscv_savefpu, function
94
95riscv_savefpu:
96	LOAD	t0, REG_INT_CTX(a0)
97	li		t1, FS_MASK
98	and		t2, t0, t1
99	li		t1, FS_DIRTY
100	bne		t2, t1, 1f
101	li		t1, ~FS_MASK
102	and		t0, t0, t1
103	li		t1, FS_CLEAN
104	or		t0, t0, t1
105	STORE	t0, REG_INT_CTX(a0)
106
107	/* Store all floating point registers */
108riscv_savefpu_force:
109
110	FSTORE		f0,  REG_F0(a0)
111	FSTORE		f1,  REG_F1(a0)
112	FSTORE		f2,  REG_F2(a0)
113	FSTORE		f3,  REG_F3(a0)
114	FSTORE		f4,  REG_F4(a0)
115	FSTORE		f5,  REG_F5(a0)
116	FSTORE		f6,  REG_F6(a0)
117	FSTORE		f7,  REG_F7(a0)
118	FSTORE		f8,  REG_F8(a0)
119	FSTORE		f9,  REG_F9(a0)
120	FSTORE		f10, REG_F10(a0)
121	FSTORE		f11, REG_F11(a0)
122	FSTORE		f12, REG_F12(a0)
123	FSTORE		f13, REG_F13(a0)
124	FSTORE		f14, REG_F14(a0)
125	FSTORE		f15, REG_F15(a0)
126	FSTORE		f16, REG_F16(a0)
127	FSTORE		f17, REG_F17(a0)
128	FSTORE		f18, REG_F18(a0)
129	FSTORE		f19, REG_F19(a0)
130	FSTORE		f20, REG_F20(a0)
131	FSTORE		f21, REG_F21(a0)
132	FSTORE		f22, REG_F22(a0)
133	FSTORE		f23, REG_F23(a0)
134	FSTORE		f24, REG_F24(a0)
135	FSTORE		f25, REG_F25(a0)
136	FSTORE		f26, REG_F26(a0)
137	FSTORE		f27, REG_F27(a0)
138	FSTORE		f28, REG_F28(a0)
139	FSTORE		f29, REG_F29(a0)
140	FSTORE		f30, REG_F30(a0)
141	FSTORE		f31, REG_F31(a0)
142
143	frcsr		t0
144	STORE		t0, REG_FCSR(a0)
145
1461:
147	ret
148
149/************************************************************************************
150 * Name: riscv_restorefpu
151 *
152 * Description:
153 *   Given the pointer to a register save area (in A0), restore the state of the
154 *   floating point registers.
155 *
156 * C Function Prototype:
157 *   void riscv_restorefpu(const uintptr_t *regs);
158 *
159 * Input Parameters:
160 *   regs - A pointer to the register save area containing the floating point
161 *     registers.
162 *
163 * Returned Value:
164 *   This function does not return anything explicitly.  However, it is called from
165 *   interrupt level assembly logic that assumes that r0 is preserved.
166 *
167 ************************************************************************************/
168
169	.type		riscv_restorefpu, function
170
171riscv_restorefpu:
172	LOAD	t0, REG_INT_CTX(a0)
173	li		t1, FS_MASK
174	and		t2, t0, t1
175	li		t1, FS_INITIAL
176	ble		t2, t1, 1f
177
178	/* Load all floating point registers */
179
180	FLOAD		f0, REG_F0(a0)
181	FLOAD		f1, REG_F1(a0)
182	FLOAD		f2, REG_F2(a0)
183	FLOAD		f3, REG_F3(a0)
184	FLOAD		f4, REG_F4(a0)
185	FLOAD		f5, REG_F5(a0)
186	FLOAD		f6, REG_F6(a0)
187	FLOAD		f7, REG_F7(a0)
188	FLOAD		f8, REG_F8(a0)
189	FLOAD		f9, REG_F9(a0)
190	FLOAD		f10, REG_F10(a0)
191	FLOAD		f11, REG_F11(a0)
192	FLOAD		f12, REG_F12(a0)
193	FLOAD		f13, REG_F13(a0)
194	FLOAD		f14, REG_F14(a0)
195	FLOAD		f15, REG_F15(a0)
196	FLOAD		f16, REG_F16(a0)
197	FLOAD		f17, REG_F17(a0)
198	FLOAD		f18, REG_F18(a0)
199	FLOAD		f19, REG_F19(a0)
200	FLOAD		f20, REG_F20(a0)
201	FLOAD		f21, REG_F21(a0)
202	FLOAD		f22, REG_F22(a0)
203	FLOAD		f23, REG_F23(a0)
204	FLOAD		f24, REG_F24(a0)
205	FLOAD		f25, REG_F25(a0)
206	FLOAD		f26, REG_F26(a0)
207	FLOAD		f27, REG_F27(a0)
208	FLOAD		f28, REG_F28(a0)
209	FLOAD		f29, REG_F29(a0)
210	FLOAD		f30, REG_F30(a0)
211	FLOAD		f31, REG_F31(a0)
212
213	/* Store the floating point control and status register */
214
215	LOAD		t0, REG_FCSR(a0)
216	fscsr		t0
217
2181:
219	ret
220
221#endif /* CONFIG_ARCH_FPU */
222