]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - lib/libkse/arch/powerpc/powerpc/context.S
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / lib / libkse / arch / powerpc / powerpc / context.S
1 /*
2  * Copyright (c) 2004 Peter Grehan.
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. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
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 #include <machine/asm.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "assym.s"
31
32 /*
33  * int _ppc32_getcontext(mcontext_t *mcp)
34  *
35  *   Save register state from a voluntary context switch.
36  * Only volatile registers, and those needed to complete
37  * a setcontext call, need to be saved.
38  *
39  *      r1
40  *      r14-31
41  *      f14-31          XXX
42  *      lr
43  *
44  *  Return 0 for this call, and set up the context so it will return
45  * 1 when restored with _ppc32_setcontext().
46  *
47  * XXX XXX
48  *  Floating-point is a big issue. Since there's no way to determine
49  * if the caller has used FP, all volatile register need to be saved.
50  * If FP hasn't been used, this results in a lazy FP exception in
51  * the kernel and from that point on FP is always switched in/out
52  * for the thread, which may be a big performance drag for the system.
53  *  An alternative is to use a system call to get the context, which
54  * will do the right thing for floating point, but will save all
55  * registers rather than the caller-saved subset, and has the overhead
56  * of a syscall.
57  *  Maybe another option would be to give a light-weight way for a
58  * thread to determine if FP is in used: perhaps a syscall that
59  * returns in the asm traphandler, or an OSX-style read-only page
60  * with a flag to indicate FP state.
61  *
62  * For now, punt the issue ala Alpha 1:1 model and fix in the future.
63  */
64 ENTRY(_ppc32_getcontext)
65         stw     %r1,  _MC_R1(%r3)
66         stw     %r13, _MC_R13(%r3)
67         stw     %r14, _MC_R14(%r3)
68         stw     %r15, _MC_R15(%r3)
69         stw     %r16, _MC_R16(%r3)
70         stw     %r17, _MC_R17(%r3)
71         stw     %r18, _MC_R18(%r3)
72         stw     %r19, _MC_R19(%r3)
73         stw     %r20, _MC_R20(%r3)
74         stw     %r21, _MC_R21(%r3)
75         stw     %r22, _MC_R22(%r3)
76         stw     %r23, _MC_R23(%r3)
77         stw     %r24, _MC_R24(%r3)
78         stw     %r25, _MC_R25(%r3)
79         stw     %r26, _MC_R26(%r3)
80         stw     %r27, _MC_R27(%r3)
81         stw     %r28, _MC_R28(%r3)
82         stw     %r29, _MC_R28(%r3)
83         stw     %r30, _MC_R30(%r3)
84         stw     %r31, _MC_R31(%r3)
85         mflr    %r4
86         stw     %r4,  _MC_LR(%r3)
87         mfcr    %r4
88         stw     %r4,  _MC_CR(%r3)
89
90         /* XXX f14-31 ? */
91
92         li      %r4, _MC_VERSION_KSE    /* partial ucontext version */
93         stw     %r4, _MC_VERS(%r3)
94
95         /* Return 0 */
96         li      %r3, 0
97         blr
98
99 /*
100  *      int _ppc32_setcontext(const mcontext_t *mcp, intptr_t val,
101  *          intptr_t *loc);
102  *
103  *  Should only be called for partial KSE contexts. The full context
104  * case is handled by kse_switchin() in _thread_switch()
105  *
106  *  Returns -1 on error and 1 for return from a saved context
107  */
108
109 ENTRY(_ppc32_setcontext)
110         lwz     %r6, _MC_VERS(%r3)
111         cmpwi   %r6, _MC_VERSION_KSE    /* KSE partial context ? */
112         beq     1f
113         li      %r3, -1                 /* invalid context type, return -1 */
114         blr
115
116 1:      /* partial format, callee-saved regs assumed */
117         lwz     %r1,  _MC_R1(%r3)
118         lwz     %r13, _MC_R13(%r3)
119         lwz     %r14, _MC_R14(%r3)
120         lwz     %r15, _MC_R15(%r3)
121         lwz     %r16, _MC_R16(%r3)
122         lwz     %r17, _MC_R17(%r3)
123         lwz     %r18, _MC_R18(%r3)
124         lwz     %r19, _MC_R19(%r3)
125         lwz     %r20, _MC_R20(%r3)
126         lwz     %r21, _MC_R21(%r3)
127         lwz     %r22, _MC_R22(%r3)
128         lwz     %r23, _MC_R23(%r3)
129         lwz     %r24, _MC_R24(%r3)
130         lwz     %r25, _MC_R25(%r3)
131         lwz     %r26, _MC_R26(%r3)
132         lwz     %r27, _MC_R27(%r3)
133         lwz     %r28, _MC_R28(%r3)
134         lwz     %r29, _MC_R28(%r3)
135         lwz     %r30, _MC_R30(%r3)
136         lwz     %r31, _MC_R31(%r3)
137         lwz     %r6,  _MC_LR(%r3)
138         mtlr    %r6
139         lwz     %r6,  _MC_CR(%r3)
140         mtcr    %r6
141
142         /*  XXX f14-31 ? */
143
144         /* if (loc != NULL) *loc = val */
145         cmpwi   %r5, 0
146         beq     2f
147         stw     %r4, 0(%r5)
148
149         /* Return 1 */
150 2:      li      %r3, 1
151         blr