]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libpthread/arch/alpha/alpha/context.S
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / lib / libpthread / arch / alpha / alpha / context.S
1 /*
2  * Copyright (c) 2001,3 Daniel Eischen <deischen@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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
24  * SUCH DAMAGE.
25  */
26 /*
27  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
28  * All rights reserved.
29  *
30  * Author: Chris G. Demetriou
31  * 
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.
37  * 
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.
41  * 
42  * Carnegie Mellon requests users of this software to return to
43  *
44  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
45  *  School of Computer Science
46  *  Carnegie Mellon University
47  *  Pittsburgh PA 15213-3890
48  *
49  * any improvements or extensions that they make and grant Carnegie the
50  * rights to redistribute these changes.
51  *
52  */
53
54 #include <machine/asm.h>
55 __FBSDID("$FreeBSD$");
56
57 /* #include <machine/frame.h> */
58 #define FRAME_V0                0
59 #define FRAME_T0                1
60 #define FRAME_T1                2
61 #define FRAME_T2                3
62 #define FRAME_T3                4
63 #define FRAME_T4                5
64 #define FRAME_T5                6
65 #define FRAME_T6                7
66 #define FRAME_T7                8
67 #define FRAME_S0                9
68 #define FRAME_S1                10
69 #define FRAME_S2                11
70 #define FRAME_S3                12
71 #define FRAME_S4                13
72 #define FRAME_S5                14
73 #define FRAME_S6                15
74 #define FRAME_A3                16
75 #define FRAME_A4                17
76 #define FRAME_A5                18
77 #define FRAME_RA                23
78 #define FRAME_T12               24
79 #define FRAME_AT                25
80 #define FRAME_SP                26
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)
85
86 /* #include <machine/reg.h> */
87 #define R_V0    0
88 #define R_T0    1
89 #define R_T1    2
90 #define R_T2    3
91 #define R_T3    4
92 #define R_T4    5
93 #define R_T5    6
94 #define R_T6    7
95 #define R_T7    8
96 #define R_S0    9
97 #define R_S1    10
98 #define R_S2    11
99 #define R_S3    12
100 #define R_S4    13
101 #define R_S5    14
102 #define R_S6    15
103 #define R_A0    16
104 #define R_A1    17
105 #define R_A2    18
106 #define R_A3    19
107 #define R_A4    20
108 #define R_A5    21
109 #define R_T8    22
110 #define R_T9    23
111 #define R_T10   24
112 #define R_T11   25
113 #define R_RA    26
114 #define R_T12   27
115 #define R_SP    30
116 #define R_ZERO  31
117
118 /*
119  * XXX - The rev id's are defined in <machine/ucontext.h>
120  */
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 */
124
125 /*
126  * int _alpha_restore_context(const mcontext_t *mcp,
127  *          intptr_t val, intptr_t *loc);
128  *
129  *   The format of the context is verified at the beginning.
130  *   Returns -1 if invalid format.
131  */
132         .set    noreorder
133 LEAF(_alpha_restore_context, 3)
134         LDGP(pv)
135         bne     a0, Lsc1                        /* argument null? */
136 Lscbad: ldiq    v0, -1                          /* return -1 */
137         br      Lscend
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? */
144         beq     t0, Lscbad
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] */
148         cmpeq   t0, t1, t0
149         beq     t0, Lscbad
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)
181         .set noat
182         ldt     $f28, ((65 + 1) * 8)(a0)
183         .set at
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 */
188         mt_fpcr ft0
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? */
192         bne     t0, Lsc_sc
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 */
219         .set noat
220         ldq     at_reg, ((FRAME_PC + 1) * 8)(a0) /* PC at time of trap? */
221         .set at
222         ldq     a3, ((FRAME_A3 + 1) * 8)(a0)    /* restore a3 */
223         ldq     a0, ((FRAME_TRAPARG_A0 + 1) * 8)(a0)    /* restore a0 */
224         br      Lsc3
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 */
253 Lsc3:   beq     a2, Lsc4
254         stq     a1, 0(a2)
255 Lsc4:   ldq     a1, 0(sp)               /* restore a1, a2 */
256         ldq     a2, 8(sp)
257         addq    sp, 16, sp              /* restore stack */
258 Lscend: RET
259 END(_alpha_restore_context)
260
261
262 /*
263  * int _alpha_save_context(mcontext_t *);
264  *
265  *   Always save in trapframe format.  Floating point registers are
266  *   saved but may be optimized away later (see comments below).
267  */
268 LEAF(_alpha_save_context, 1)
269         LDGP(pv)
270         bne     a0, Lgc1                        /* argument null? */
271         ldiq    v0, -1                          /* return -1 */
272         br      Lgcend
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 */
300         /*
301          * XXX - Do we really need to save floating point registers?
302          *
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.
307          */
308 #if 1
309         stq     zero, ((71 + 1) * 8)(a0)        /* FP regs are not saved */
310 #else
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)
341         .set noat
342         stt     $f28, ((65 + 1) * 8)(a0)
343         .set at
344         stt     $f29, ((66 + 1) * 8)(a0)
345         stt     $f30, ((67 + 1) * 8)(a0)
346         /* $f31 is hardwired zero */
347 #endif
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 */
352 Lgcend: RET
353 END(_alpha_save_context)