2 * Copyright (c) 2001,3 Daniel Eischen <deischen@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Neither the name of the author nor the names of its contributors
11 * may be used to endorse or promote products derived from this software
12 * without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Copyright (c) 1994, 1995 Carnegie-Mellon University.
28 * All rights reserved.
30 * Author: Chris G. Demetriou
32 * Permission to use, copy, modify and distribute this software and
33 * its documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
40 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
54 #include <machine/asm.h>
55 __FBSDID("$FreeBSD$");
57 /* #include <machine/frame.h> */
81 #define FRAME_TRAPARG_A0 28
82 #define FRAME_TRAPARG_A1 29
83 #define FRAME_TRAPARG_A2 30
84 #define FRAME_PC (FRAME_TRAPARG_A2 + 1 + 1)
86 /* #include <machine/reg.h> */
119 * XXX - The rev id's are defined in <machine/ucontext.h>
121 #define MC_FMT_OFFSET 73*8 /* offset to format from mcontext */
122 #define REV0_SIGFRAME 0x0001 /* rev R0 sigcontext format */
123 #define REV0_TRAPFRAME 0x0002 /* rev R0 trapframe format */
126 * int _alpha_restore_context(const mcontext_t *mcp,
127 * intptr_t val, intptr_t *loc);
129 * The format of the context is verified at the beginning.
130 * Returns -1 if invalid format.
133 LEAF(_alpha_restore_context, 3)
135 bne a0, Lsc1 /* argument null? */
136 Lscbad: ldiq v0, -1 /* return -1 */
138 Lsc1: ldq t1, MC_FMT_OFFSET(a0) /* is mcontext valid format? */
139 ldiq t0, REV0_TRAPFRAME
140 cmpeq t0, t1, t0 /* is it trapframe format? */
141 bne t0, Lsc_fp /* if so, check fp state */
142 ldiq t0, REV0_SIGFRAME
143 cmpeq t0, t1, t0 /* is it sigcontext format? */
145 /* supposedly sigcontext format, check magic number */
146 ldiq t0, 0xACEDBADE /* check magic number */
147 ldq t1, ((R_ZERO + 1) * 8)(a0) /* magic in mc_regs[R_ZERO] */
150 /* restore floating point regs first */
151 Lsc_fp: ldq t0, ((71 + 1) * 8)(a0) /* if FP regs not saved, */
152 beq t0, Lsc2 /* skip setting FP regs */
153 ldt $f0, ((37 + 1) * 8)(a0) /* restore FP regs using */
154 ldt $f1, ((38 + 1) * 8)(a0) /* hw name */
155 ldt $f2, ((39 + 1) * 8)(a0)
156 ldt $f3, ((40 + 1) * 8)(a0)
157 ldt $f4, ((41 + 1) * 8)(a0)
158 ldt $f5, ((42 + 1) * 8)(a0)
159 ldt $f6, ((43 + 1) * 8)(a0)
160 ldt $f7, ((44 + 1) * 8)(a0)
161 ldt $f8, ((45 + 1) * 8)(a0)
162 ldt $f9, ((46 + 1) * 8)(a0)
163 ldt $f10, ((47 + 1) * 8)(a0)
164 ldt $f11, ((48 + 1) * 8)(a0)
165 ldt $f12, ((49 + 1) * 8)(a0)
166 ldt $f13, ((50 + 1) * 8)(a0)
167 ldt $f14, ((51 + 1) * 8)(a0)
168 ldt $f15, ((52 + 1) * 8)(a0)
169 ldt $f16, ((53 + 1) * 8)(a0)
170 ldt $f17, ((54 + 1) * 8)(a0)
171 ldt $f18, ((55 + 1) * 8)(a0)
172 ldt $f19, ((56 + 1) * 8)(a0)
173 ldt $f20, ((57 + 1) * 8)(a0)
174 ldt $f21, ((58 + 1) * 8)(a0)
175 ldt $f22, ((59 + 1) * 8)(a0)
176 ldt $f23, ((60 + 1) * 8)(a0)
177 ldt $f24, ((61 + 1) * 8)(a0)
178 ldt $f25, ((62 + 1) * 8)(a0)
179 ldt $f26, ((63 + 1) * 8)(a0)
180 ldt $f27, ((64 + 1) * 8)(a0)
182 ldt $f28, ((65 + 1) * 8)(a0)
184 ldt $f29, ((66 + 1) * 8)(a0)
185 ldt $f30, ((67 + 1) * 8)(a0)
186 /* $f31 is hardwired zero */
187 ldt ft0, ((69 + 1) * 8)(a0) /* restore FP control reg */
189 Lsc2: ldiq t0, REV0_SIGFRAME /* check the context format */
190 ldq t1, MC_FMT_OFFSET(a0) /* again. */
191 cmpeq t0, t1, t0 /* is it sigcontext format? */
193 /* trapframe format */
194 ldq v0, ((FRAME_V0 + 1) * 8)(a0) /* restore v0 */
195 ldq t0, ((FRAME_T0 + 1) * 8)(a0) /* restore t0-t7 */
196 ldq t1, ((FRAME_T1 + 1) * 8)(a0)
197 ldq t2, ((FRAME_T2 + 1) * 8)(a0)
198 ldq t3, ((FRAME_T3 + 1) * 8)(a0)
199 ldq t4, ((FRAME_T4 + 1) * 8)(a0)
200 ldq t5, ((FRAME_T5 + 1) * 8)(a0)
201 ldq t6, ((FRAME_T6 + 1) * 8)(a0)
202 ldq t7, ((FRAME_T7 + 1) * 8)(a0)
203 ldq s0, ((FRAME_S0 + 1) * 8)(a0) /* restore s0-s6 */
204 ldq s1, ((FRAME_S1 + 1) * 8)(a0)
205 ldq s2, ((FRAME_S2 + 1) * 8)(a0)
206 ldq s3, ((FRAME_S3 + 1) * 8)(a0)
207 ldq s4, ((FRAME_S4 + 1) * 8)(a0)
208 ldq s5, ((FRAME_S5 + 1) * 8)(a0)
209 ldq s6, ((FRAME_S6 + 1) * 8)(a0)
210 ldq a4, ((FRAME_A4 + 1) * 8)(a0) /* restore a4, a5 */
211 ldq a5, ((FRAME_A5 + 1) * 8)(a0)
212 ldq ra, ((FRAME_RA + 1) * 8)(a0)
213 ldq sp, ((FRAME_SP + 1) * 8)(a0)
214 subq sp, 16, sp /* save room on stack */
215 ldq a3, ((FRAME_TRAPARG_A1 + 1) * 8)(a0)
216 stq a3, 0(a0) /* save a1 on stack */
217 ldq a3, ((FRAME_TRAPARG_A2 + 1) * 8)(a0)
218 stq a3, 8(a0) /* save a2 on stack */
220 ldq at_reg, ((FRAME_PC + 1) * 8)(a0) /* PC at time of trap? */
222 ldq a3, ((FRAME_A3 + 1) * 8)(a0) /* restore a3 */
223 ldq a0, ((FRAME_TRAPARG_A0 + 1) * 8)(a0) /* restore a0 */
225 Lsc_sc: /* sigcontext format */
226 ldq v0, ((R_V0 + 1) * 8)(a0) /* restore v0 */
227 ldq t0, ((R_T0 + 1) * 8)(a0) /* restore t0-t7 */
228 ldq t1, ((R_T1 + 1) * 8)(a0)
229 ldq t2, ((R_T2 + 1) * 8)(a0)
230 ldq t3, ((R_T3 + 1) * 8)(a0)
231 ldq t4, ((R_T4 + 1) * 8)(a0)
232 ldq t5, ((R_T5 + 1) * 8)(a0)
233 ldq t6, ((R_T6 + 1) * 8)(a0)
234 ldq t7, ((R_T7 + 1) * 8)(a0)
235 ldq s0, ((R_S0 + 1) * 8)(a0) /* restore s0-s6 */
236 ldq s1, ((R_S1 + 1) * 8)(a0)
237 ldq s2, ((R_S2 + 1) * 8)(a0)
238 ldq s3, ((R_S3 + 1) * 8)(a0)
239 ldq s4, ((R_S4 + 1) * 8)(a0)
240 ldq s5, ((R_S5 + 1) * 8)(a0)
241 ldq s6, ((R_S6 + 1) * 8)(a0)
242 ldq a4, ((R_A4 + 1) * 8)(a0) /* restore a4, a5 */
243 ldq a5, ((R_A5 + 1) * 8)(a0)
244 ldq ra, ((R_RA + 1) * 8)(a0)
245 ldq sp, ((R_SP + 1) * 8)(a0)
246 subq sp, 16, sp /* save room on stack */
247 ldq a3, ((R_A1 + 1) * 8)(a0) /* get a1 */
248 stq a3, 0(a0) /* save a1 on stack */
249 ldq a3, ((R_A2 + 1) * 8)(a0) /* get a2 */
250 stq a3, 8(a0) /* save a2 on stack */
251 ldq a3, ((R_A3 + 1) * 8)(a0) /* restore a3 */
252 ldq a0, ((R_A0 + 1) * 8)(a0) /* restore a0 */
255 Lsc4: ldq a1, 0(sp) /* restore a1, a2 */
257 addq sp, 16, sp /* restore stack */
259 END(_alpha_restore_context)
263 * int _alpha_save_context(mcontext_t *);
265 * Always save in trapframe format. Floating point registers are
266 * saved but may be optimized away later (see comments below).
268 LEAF(_alpha_save_context, 1)
270 bne a0, Lgc1 /* argument null? */
271 ldiq v0, -1 /* return -1 */
273 Lgc1: ldiq v0, 1 /* save_context returns 1, */
274 stq v0, ((FRAME_V0 + 1) * 8)(a0) /* so save 1 in v0 */
275 stq t0, ((FRAME_T0 + 1) * 8)(a0) /* save t0-t7 */
276 stq t1, ((FRAME_T1 + 1) * 8)(a0)
277 stq t2, ((FRAME_T2 + 1) * 8)(a0)
278 stq t3, ((FRAME_T3 + 1) * 8)(a0)
279 stq t4, ((FRAME_T4 + 1) * 8)(a0)
280 stq t5, ((FRAME_T5 + 1) * 8)(a0)
281 stq t6, ((FRAME_T6 + 1) * 8)(a0)
282 stq t7, ((FRAME_T7 + 1) * 8)(a0)
283 stq s0, ((FRAME_S0 + 1) * 8)(a0) /* save s0-s6 */
284 stq s1, ((FRAME_S1 + 1) * 8)(a0)
285 stq s2, ((FRAME_S2 + 1) * 8)(a0)
286 stq s3, ((FRAME_S3 + 1) * 8)(a0)
287 stq s4, ((FRAME_S4 + 1) * 8)(a0)
288 stq s5, ((FRAME_S5 + 1) * 8)(a0)
289 stq s6, ((FRAME_S6 + 1) * 8)(a0)
290 stq a0, ((FRAME_TRAPARG_A0 + 1) * 8)(a0) /* save a0-a5 */
291 stq a1, ((FRAME_TRAPARG_A1 + 1) * 8)(a0)
292 stq a2, ((FRAME_TRAPARG_A2 + 1) * 8)(a0)
293 stq a3, ((FRAME_A3 + 1) * 8)(a0)
294 stq a4, ((FRAME_A4 + 1) * 8)(a0)
295 stq a5, ((FRAME_A5 + 1) * 8)(a0)
296 stq ra, ((FRAME_RA + 1) * 8)(a0)
297 stq sp, ((FRAME_SP + 1) * 8)(a0)
298 ldiq t0, REV0_TRAPFRAME /* store trapframe format in */
299 stq t0, MC_FMT_OFFSET(a0) /* ucp->uc-rev */
301 * XXX - Do we really need to save floating point registers?
303 * This is an explicit call to get the current context, so
304 * shouldn't the caller be done with the floating point registers?
305 * Contexts formed by involuntary switches, such as signal delivery,
306 * should have floating point registers saved by the kernel.
309 stq zero, ((71 + 1) * 8)(a0) /* FP regs are not saved */
311 ldiq t0, 1 /* say we've used FP, */
312 stq t0, ((71 + 1) * 8)(a0) /* mc_ownedfp = 1 */
313 stt $f0, ((37 + 1) * 8)(a0) /* save first register, using */
314 stt $f1, ((38 + 1) * 8)(a0) /* hw name etc. */
315 stt $f2, ((39 + 1) * 8)(a0)
316 stt $f3, ((40 + 1) * 8)(a0)
317 stt $f4, ((41 + 1) * 8)(a0)
318 stt $f5, ((42 + 1) * 8)(a0)
319 stt $f6, ((43 + 1) * 8)(a0)
320 stt $f7, ((44 + 1) * 8)(a0)
321 stt $f8, ((45 + 1) * 8)(a0)
322 stt $f9, ((46 + 1) * 8)(a0)
323 stt $f10, ((47 + 1) * 8)(a0)
324 stt $f11, ((48 + 1) * 8)(a0)
325 stt $f12, ((49 + 1) * 8)(a0)
326 stt $f13, ((50 + 1) * 8)(a0)
327 stt $f14, ((51 + 1) * 8)(a0)
328 stt $f15, ((52 + 1) * 8)(a0)
329 stt $f16, ((53 + 1) * 8)(a0)
330 stt $f17, ((54 + 1) * 8)(a0)
331 stt $f18, ((55 + 1) * 8)(a0)
332 stt $f19, ((56 + 1) * 8)(a0)
333 stt $f20, ((57 + 1) * 8)(a0)
334 stt $f21, ((58 + 1) * 8)(a0)
335 stt $f22, ((59 + 1) * 8)(a0)
336 stt $f23, ((60 + 1) * 8)(a0)
337 stt $f24, ((61 + 1) * 8)(a0)
338 stt $f25, ((62 + 1) * 8)(a0)
339 stt $f26, ((63 + 1) * 8)(a0)
340 stt $f27, ((64 + 1) * 8)(a0)
342 stt $f28, ((65 + 1) * 8)(a0)
344 stt $f29, ((66 + 1) * 8)(a0)
345 stt $f30, ((67 + 1) * 8)(a0)
346 /* $f31 is hardwired zero */
348 mf_fpcr ft0 /* get FP control reg */
349 stt ft0, ((69 + 1) * 8)(a0) /* and store it in mc_fpcr */
350 stq zero, ((70 + 1) * 8)(a0) /* FP software control XXX */
351 mov zero, v0 /* return zero */
353 END(_alpha_save_context)