]>
Commit | Line | Data |
---|---|---|
a86a7a39 | 1 | /* Install given context. |
b168057a | 2 | Copyright (C) 2008-2015 Free Software Foundation, Inc. |
a86a7a39 JJ |
3 | This file is part of the GNU C Library. |
4 | Contributed by David S. Miller <davem@davemloft.net>, 2008. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
10 | ||
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
a86a7a39 JJ |
19 | |
20 | #include <sysdep.h> | |
21 | #include <sys/trap.h> | |
22 | ||
23 | #include "ucontext_i.h" | |
24 | ||
25 | ||
26 | /* int __setcontext (const ucontext_t *ucp) | |
27 | ||
28 | Restores the machine context in UCP and thereby resumes execution | |
29 | in that context. | |
30 | ||
31 | This implementation is intended to be used for *synchronous* context | |
32 | switches only. Therefore, it does not have to restore anything | |
33 | other than the PRESERVED state. */ | |
34 | ||
35 | ENTRY(__setcontext) | |
36 | save %sp, -112, %sp | |
37 | ||
38 | mov SIG_SETMASK, %o0 | |
39 | add %i0, UC_SIGMASK, %o1 | |
40 | clr %o2 | |
41 | mov 8, %o3 | |
42 | mov __NR_rt_sigprocmask, %g1 | |
43 | ta 0x10 | |
44 | ||
45 | /* This is a bit on the expensive side, and we could optimize | |
46 | the unwind similar to how the 32-bit sparc longjmp code | |
47 | does if performance of this routine really matters. */ | |
48 | ta ST_FLUSH_WINDOWS | |
49 | ||
50 | ldub [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_EN], %g1 | |
51 | cmp %g1, 0 | |
52 | be 1f | |
53 | nop | |
54 | ld [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_FSR], %fsr | |
55 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D0], %f0 | |
56 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D2], %f2 | |
57 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D4], %f4 | |
58 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D6], %f6 | |
59 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D8], %f8 | |
60 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D10], %f10 | |
61 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D12], %f12 | |
62 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D14], %f14 | |
63 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D16], %f16 | |
64 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D18], %f18 | |
65 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D20], %f20 | |
66 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D22], %f22 | |
67 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D24], %f24 | |
68 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D26], %f26 | |
69 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D28], %f28 | |
70 | ldd [%i0 + UC_MCONTEXT + MC_FPREGS + FPU_D30], %f30 | |
71 | 1: | |
72 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_Y], %g1 | |
73 | wr %g1, 0x0, %y | |
74 | ||
75 | /* We specifically do not restore %g1 since we need it here as | |
76 | a temporary. */ | |
77 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G2], %g2 | |
78 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G3], %g3 | |
79 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G4], %g4 | |
80 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G5], %g5 | |
81 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G6], %g6 | |
82 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_G7], %g7 | |
83 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O1], %i1 | |
84 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O2], %i2 | |
85 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O3], %i3 | |
86 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O4], %i4 | |
87 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O5], %i5 | |
88 | ld [%i0 + UC_MCONTEXT + MC_GREGS + GREG_O6], %i6 | |
89 | restore | |
90 | ld [%o0 + UC_MCONTEXT + MC_GREGS + GREG_O7], %o7 | |
91 | ld [%o0 + UC_MCONTEXT + MC_GREGS + GREG_PC], %g1 | |
92 | jmpl %g1, %g0 | |
93 | ld [%o0 + UC_MCONTEXT + MC_GREGS + GREG_O0], %o0 | |
94 | END(__setcontext) | |
95 | ||
96 | weak_alias (__setcontext, setcontext) | |
97 | ||
98 | /* This is the helper code which gets called if a function which is | |
99 | registered with 'makecontext' returns. In this case we have to | |
100 | install the context listed in the uc_link element of the context | |
101 | 'makecontext' manipulated at the time of the 'makecontext' call. | |
102 | If the pointer is NULL the process must terminate. */ | |
103 | ||
104 | ENTRY(__start_context) | |
105 | ld [%sp + (16 * 4)], %g1 | |
106 | cmp %g1, 0 | |
107 | be,a 1f | |
108 | clr %o0 | |
109 | call __setcontext | |
110 | mov %g1, %o0 | |
111 | /* If this returns (which can happen if the syscall fails) we'll | |
112 | exit the program with the return error value (-1). */ | |
86746abb | 113 | 1: call HIDDEN_JUMPTARGET(exit) |
a86a7a39 JJ |
114 | nop |
115 | /* The 'exit' call should never return. In case it does cause | |
116 | the process to terminate. */ | |
117 | unimp | |
118 | END(__start_context) |