| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: vm_machdep.c,v 1.98 2009/05/16 17:01:15 cegger Exp $ */ | | 1 | /* $NetBSD: vm_machdep.c,v 1.99 2009/05/27 04:08:06 mrg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996 | | 4 | * Copyright (c) 1996 |
5 | * The President and Fellows of Harvard College. All rights reserved. | | 5 | * The President and Fellows of Harvard College. All rights reserved. |
6 | * Copyright (c) 1992, 1993 | | 6 | * Copyright (c) 1992, 1993 |
7 | * The Regents of the University of California. All rights reserved. | | 7 | * The Regents of the University of California. All rights reserved. |
8 | * | | 8 | * |
9 | * This software was developed by the Computer Systems Engineering group | | 9 | * This software was developed by the Computer Systems Engineering group |
10 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | | 10 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
11 | * contributed to Berkeley. | | 11 | * contributed to Berkeley. |
12 | * | | 12 | * |
13 | * All advertising materials mentioning features or use of this software | | 13 | * All advertising materials mentioning features or use of this software |
14 | * must display the following acknowledgement: | | 14 | * must display the following acknowledgement: |
| @@ -39,27 +39,27 @@ | | | @@ -39,27 +39,27 @@ |
39 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 39 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
40 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 40 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
41 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 41 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
42 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 42 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
44 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 44 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
45 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 45 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
46 | * SUCH DAMAGE. | | 46 | * SUCH DAMAGE. |
47 | * | | 47 | * |
48 | * @(#)vm_machdep.c 8.2 (Berkeley) 9/23/93 | | 48 | * @(#)vm_machdep.c 8.2 (Berkeley) 9/23/93 |
49 | */ | | 49 | */ |
50 | | | 50 | |
51 | #include <sys/cdefs.h> | | 51 | #include <sys/cdefs.h> |
52 | __KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.98 2009/05/16 17:01:15 cegger Exp $"); | | 52 | __KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.99 2009/05/27 04:08:06 mrg Exp $"); |
53 | | | 53 | |
54 | #include "opt_multiprocessor.h" | | 54 | #include "opt_multiprocessor.h" |
55 | | | 55 | |
56 | #include <sys/param.h> | | 56 | #include <sys/param.h> |
57 | #include <sys/systm.h> | | 57 | #include <sys/systm.h> |
58 | #include <sys/proc.h> | | 58 | #include <sys/proc.h> |
59 | #include <sys/user.h> | | 59 | #include <sys/user.h> |
60 | #include <sys/core.h> | | 60 | #include <sys/core.h> |
61 | #include <sys/malloc.h> | | 61 | #include <sys/malloc.h> |
62 | #include <sys/buf.h> | | 62 | #include <sys/buf.h> |
63 | #include <sys/exec.h> | | 63 | #include <sys/exec.h> |
64 | #include <sys/vnode.h> | | 64 | #include <sys/vnode.h> |
65 | #include <sys/simplelock.h> | | 65 | #include <sys/simplelock.h> |
| @@ -197,26 +197,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp | | | @@ -197,26 +197,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp |
197 | * user registers and invalid stack pointers, to opcb. | | 197 | * user registers and invalid stack pointers, to opcb. |
198 | * We then copy the whole pcb to l2; when switch() selects l2 | | 198 | * We then copy the whole pcb to l2; when switch() selects l2 |
199 | * to run, it will run at the `lwp_trampoline' stub, rather | | 199 | * to run, it will run at the `lwp_trampoline' stub, rather |
200 | * than returning at the copying code below. | | 200 | * than returning at the copying code below. |
201 | * | | 201 | * |
202 | * If process l1 has an FPU state, we must copy it. If it is | | 202 | * If process l1 has an FPU state, we must copy it. If it is |
203 | * the FPU user, we must save the FPU state first. | | 203 | * the FPU user, we must save the FPU state first. |
204 | */ | | 204 | */ |
205 | | | 205 | |
206 | if (l1 == curlwp) { | | 206 | if (l1 == curlwp) { |
207 | write_user_windows(); | | 207 | write_user_windows(); |
208 | opcb->pcb_psr = getpsr(); | | 208 | opcb->pcb_psr = getpsr(); |
209 | } | | 209 | } |
| | | 210 | #ifdef DIAGNOSTIC |
| | | 211 | else if (l1 != &lwp0) /* XXX is this valid? */ |
| | | 212 | panic("cpu_lwp_fork: curlwp"); |
| | | 213 | #endif |
210 | | | 214 | |
211 | memcpy((void *)npcb, (void *)opcb, sizeof(struct pcb)); | | 215 | memcpy((void *)npcb, (void *)opcb, sizeof(struct pcb)); |
212 | if (l1->l_md.md_fpstate != NULL) { | | 216 | if (l1->l_md.md_fpstate != NULL) { |
213 | struct cpu_info *cpi; | | 217 | struct cpu_info *cpi; |
214 | int s; | | 218 | int s; |
215 | | | 219 | |
216 | l2->l_md.md_fpstate = malloc(sizeof(struct fpstate), | | 220 | l2->l_md.md_fpstate = malloc(sizeof(struct fpstate), |
217 | M_SUBPROC, M_WAITOK); | | 221 | M_SUBPROC, M_WAITOK); |
218 | | | 222 | |
219 | FPU_LOCK(s); | | 223 | FPU_LOCK(s); |
220 | if ((cpi = l1->l_md.md_fpu) != NULL) { | | 224 | if ((cpi = l1->l_md.md_fpu) != NULL) { |
221 | if (cpi->fplwp != l1) | | 225 | if (cpi->fplwp != l1) |
222 | panic("FPU(%d): fplwp %p", | | 226 | panic("FPU(%d): fplwp %p", |
| @@ -261,34 +265,28 @@ cpu_lwp_fork(struct lwp *l1, struct lwp | | | @@ -261,34 +265,28 @@ cpu_lwp_fork(struct lwp *l1, struct lwp |
261 | * note: lwp_trampoline() sets a fresh psr when returning | | 265 | * note: lwp_trampoline() sets a fresh psr when returning |
262 | * to user mode. | | 266 | * to user mode. |
263 | */ | | 267 | */ |
264 | /*tf2->tf_psr &= ~PSR_C; -* success */ | | 268 | /*tf2->tf_psr &= ~PSR_C; -* success */ |
265 | tf2->tf_pc = tf2->tf_npc; | | 269 | tf2->tf_pc = tf2->tf_npc; |
266 | tf2->tf_npc = tf2->tf_pc + 4; | | 270 | tf2->tf_npc = tf2->tf_pc + 4; |
267 | | | 271 | |
268 | /* Set return values in child mode */ | | 272 | /* Set return values in child mode */ |
269 | tf2->tf_out[0] = 0; | | 273 | tf2->tf_out[0] = 0; |
270 | tf2->tf_out[1] = 1; | | 274 | tf2->tf_out[1] = 1; |
271 | | | 275 | |
272 | /* Construct kernel frame to return to in cpu_switch() */ | | 276 | /* Construct kernel frame to return to in cpu_switch() */ |
273 | rp = (struct rwindow *)((u_int)npcb + TOPFRAMEOFF); | | 277 | rp = (struct rwindow *)((u_int)npcb + TOPFRAMEOFF); |
274 | rp->rw_local[0] = (int)func; /* Function to call */ | | | |
275 | rp->rw_local[1] = (int)arg; /* and its argument */ | | | |
276 | rp->rw_local[2] = (int)l2; /* the new LWP */ | | | |
277 | | | 278 | |
278 | npcb->pcb_pc = (int)lwp_trampoline - 8; | | 279 | cpu_setfunc(l2, func, arg); |
279 | npcb->pcb_sp = (int)rp; | | | |
280 | npcb->pcb_psr &= ~PSR_CWP; /* Run in window #0 */ | | | |
281 | npcb->pcb_wim = 1; /* Fence at window #1 */ | | | |
282 | } | | 280 | } |
283 | | | 281 | |
284 | /* | | 282 | /* |
285 | * Cleanup FPU state. | | 283 | * Cleanup FPU state. |
286 | */ | | 284 | */ |
287 | void | | 285 | void |
288 | cpu_lwp_free(struct lwp *l, int proc) | | 286 | cpu_lwp_free(struct lwp *l, int proc) |
289 | { | | 287 | { |
290 | struct fpstate *fs; | | 288 | struct fpstate *fs; |
291 | | | 289 | |
292 | if ((fs = l->l_md.md_fpstate) != NULL) { | | 290 | if ((fs = l->l_md.md_fpstate) != NULL) { |
293 | struct cpu_info *cpi; | | 291 | struct cpu_info *cpi; |
294 | int s; | | 292 | int s; |