Wed Jan 18 19:17:02 2012 UTC ()
Create an atomic switchto() that has SIGALRM and SIGIO signals blocked that
might otherwise disrupt the setting of curlwp to match the lwp context.


(reinoud)
diff -r1.67 -r1.68 src/sys/arch/usermode/dev/cpu.c

cvs diff -r1.67 -r1.68 src/sys/arch/usermode/dev/cpu.c (switch to unified diff)

--- src/sys/arch/usermode/dev/cpu.c 2012/01/15 10:45:03 1.67
+++ src/sys/arch/usermode/dev/cpu.c 2012/01/18 19:17:02 1.68
@@ -1,421 +1,452 @@ @@ -1,421 +1,452 @@
1/* $NetBSD: cpu.c,v 1.67 2012/01/15 10:45:03 jmcneill Exp $ */ 1/* $NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_cpu.h" 29#include "opt_cpu.h"
30#include "opt_hz.h" 30#include "opt_hz.h"
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.67 2012/01/15 10:45:03 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/conf.h> 36#include <sys/conf.h>
37#include <sys/proc.h> 37#include <sys/proc.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/reboot.h> 40#include <sys/reboot.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/cpu.h> 42#include <sys/cpu.h>
43#include <sys/mbuf.h> 43#include <sys/mbuf.h>
44#include <sys/msgbuf.h> 44#include <sys/msgbuf.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/mount.h> 47#include <sys/mount.h>
48 48
49#include <dev/cons.h> 49#include <dev/cons.h>
50 50
51#include <machine/cpu.h> 51#include <machine/cpu.h>
52#include <machine/mainbus.h> 52#include <machine/mainbus.h>
53#include <machine/pcb.h> 53#include <machine/pcb.h>
54#include <machine/machdep.h> 54#include <machine/machdep.h>
55#include <machine/thunk.h> 55#include <machine/thunk.h>
56 56
57#include <uvm/uvm_extern.h> 57#include <uvm/uvm_extern.h>
58#include <uvm/uvm_page.h> 58#include <uvm/uvm_page.h>
59 59
60#if __GNUC_PREREQ__(4,4) 60#if __GNUC_PREREQ__(4,4)
61#define cpu_unreachable() __builtin_unreachable() 61#define cpu_unreachable() __builtin_unreachable()
62#else 62#else
63#define cpu_unreachable() do { thunk_abort(); } while (0) 63#define cpu_unreachable() do { thunk_abort(); } while (0)
64#endif 64#endif
65 65
66static int cpu_match(device_t, cfdata_t, void *); 66static int cpu_match(device_t, cfdata_t, void *);
67static void cpu_attach(device_t, device_t, void *); 67static void cpu_attach(device_t, device_t, void *);
68 68
69struct cpu_info cpu_info_primary = { 69struct cpu_info cpu_info_primary = {
70 .ci_dev = 0, 70 .ci_dev = 0,
71 .ci_self = &cpu_info_primary, 71 .ci_self = &cpu_info_primary,
72 .ci_idepth = -1, 72 .ci_idepth = -1,
73 .ci_curlwp = &lwp0, 73 .ci_curlwp = &lwp0,
74}; 74};
75 75
76char cpu_model[48] = "virtual processor"; 76char cpu_model[48] = "virtual processor";
77 77
78typedef struct cpu_softc { 78typedef struct cpu_softc {
79 device_t sc_dev; 79 device_t sc_dev;
80 struct cpu_info *sc_ci; 80 struct cpu_info *sc_ci;
 81
 82 ucontext_t sc_ucp;
 83 uint8_t sc_ucp_stack[PAGE_SIZE];
81} cpu_softc_t; 84} cpu_softc_t;
82 85
83 86
84/* statics */ 87/* statics */
85static struct pcb lwp0pcb; 88static struct pcb lwp0pcb;
86static void *um_msgbuf; 89static void *um_msgbuf;
87 90
88 91
89/* attachment */ 92/* attachment */
90CFATTACH_DECL_NEW(cpu, sizeof(cpu_softc_t), cpu_match, cpu_attach, NULL, NULL); 93CFATTACH_DECL_NEW(cpu, sizeof(cpu_softc_t), cpu_match, cpu_attach, NULL, NULL);
91 94
92static int 95static int
93cpu_match(device_t parent, cfdata_t match, void *opaque) 96cpu_match(device_t parent, cfdata_t match, void *opaque)
94{ 97{
95 struct thunkbus_attach_args *taa = opaque; 98 struct thunkbus_attach_args *taa = opaque;
96 99
97 if (taa->taa_type != THUNKBUS_TYPE_CPU) 100 if (taa->taa_type != THUNKBUS_TYPE_CPU)
98 return 0; 101 return 0;
99 102
100 return 1; 103 return 1;
101} 104}
102 105
103static void 106static void
104cpu_attach(device_t parent, device_t self, void *opaque) 107cpu_attach(device_t parent, device_t self, void *opaque)
105{ 108{
106 cpu_softc_t *sc = device_private(self); 109 cpu_softc_t *sc = device_private(self);
107 110
108 aprint_naive("\n"); 111 aprint_naive("\n");
109 aprint_normal("\n"); 112 aprint_normal("\n");
110 113
 114 cpu_info_primary.ci_dev = self;
111 sc->sc_dev = self; 115 sc->sc_dev = self;
112 sc->sc_ci = &cpu_info_primary; 116 sc->sc_ci = &cpu_info_primary;
 117
 118 thunk_getcontext(&sc->sc_ucp);
 119 sc->sc_ucp.uc_stack.ss_sp = sc->sc_ucp_stack;
 120 sc->sc_ucp.uc_stack.ss_size = PAGE_SIZE - sizeof(register_t);
 121 sc->sc_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
 122 thunk_sigaddset(&sc->sc_ucp.uc_sigmask, SIGALRM);
 123 thunk_sigaddset(&sc->sc_ucp.uc_sigmask, SIGIO);
113} 124}
114 125
115void 126void
116cpu_configure(void) 127cpu_configure(void)
117{ 128{
118 if (config_rootfound("mainbus", NULL) == NULL) 129 if (config_rootfound("mainbus", NULL) == NULL)
119 panic("configure: mainbus not configured"); 130 panic("configure: mainbus not configured");
120 131
121 spl0(); 132 spl0();
122} 133}
123 134
124 135
125/* main guts */ 136/* main guts */
126void 137void
127cpu_reboot(int howto, char *bootstr) 138cpu_reboot(int howto, char *bootstr)
128{ 139{
129 extern void usermode_reboot(void); 140 extern void usermode_reboot(void);
130 141
131 if (cold) 142 if (cold)
132 howto |= RB_HALT; 143 howto |= RB_HALT;
133 144
134 if ((howto & RB_NOSYNC) == 0) 145 if ((howto & RB_NOSYNC) == 0)
135 vfs_shutdown(); 146 vfs_shutdown();
136 else 147 else
137 suspendsched(); 148 suspendsched();
138 149
139 doshutdownhooks(); 150 doshutdownhooks();
140 pmf_system_shutdown(boothowto); 151 pmf_system_shutdown(boothowto);
141 152
142 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) 153 if ((howto & RB_POWERDOWN) == RB_POWERDOWN)
143 thunk_exit(0); 154 thunk_exit(0);
144 155
145 splhigh(); 156 splhigh();
146 157
147 if (howto & RB_DUMP) 158 if (howto & RB_DUMP)
148 thunk_abort(); 159 thunk_abort();
149 160
150 if (howto & RB_HALT) { 161 if (howto & RB_HALT) {
151 printf("\n"); 162 printf("\n");
152 printf("The operating system has halted.\n"); 163 printf("The operating system has halted.\n");
153 printf("Please press any key to reboot.\n\n"); 164 printf("Please press any key to reboot.\n\n");
154 cnpollc(1); 165 cnpollc(1);
155 cngetc(); 166 cngetc();
156 cnpollc(0); 167 cnpollc(0);
157 } 168 }
158 169
159 printf("rebooting...\n"); 170 printf("rebooting...\n");
160 171
161 usermode_reboot(); 172 usermode_reboot();
162 173
163 /* NOTREACHED */ 174 /* NOTREACHED */
164 cpu_unreachable(); 175 cpu_unreachable();
165} 176}
166 177
167void 178void
168cpu_need_resched(struct cpu_info *ci, int flags) 179cpu_need_resched(struct cpu_info *ci, int flags)
169{ 180{
170 ci->ci_want_resched |= flags; 181 ci->ci_want_resched |= flags;
171 aston(ci); 182 aston(ci);
172} 183}
173 184
174void 185void
175cpu_need_proftick(struct lwp *l) 186cpu_need_proftick(struct lwp *l)
176{ 187{
177} 188}
178 189
 190static
 191void
 192cpu_switchto_atomic(lwp_t *oldlwp, lwp_t *newlwp)
 193{
 194 struct pcb *oldpcb = oldlwp ? lwp_getpcb(oldlwp) : NULL;
 195 struct pcb *newpcb = lwp_getpcb(newlwp);
 196 struct cpu_info *ci = curcpu();
 197
 198 ci->ci_stash = oldlwp;
 199
 200 if (oldpcb)
 201 oldpcb->pcb_errno = thunk_geterrno();
 202
 203 thunk_seterrno(newpcb->pcb_errno);
 204
 205 curlwp = newlwp;
 206 if (thunk_setcontext(&newpcb->pcb_ucp))
 207 panic("setcontext failed");
 208 /* not reached */
 209}
 210
179lwp_t * 211lwp_t *
180cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning) 212cpu_switchto(lwp_t *oldlwp, lwp_t *newlwp, bool returning)
181{ 213{
182 struct pcb *oldpcb = oldlwp ? lwp_getpcb(oldlwp) : NULL; 214 struct pcb *oldpcb = oldlwp ? lwp_getpcb(oldlwp) : NULL;
183 struct pcb *newpcb = lwp_getpcb(newlwp); 215 struct pcb *newpcb = lwp_getpcb(newlwp);
184 struct cpu_info *ci = curcpu(); 216 struct cpu_info *ci = curcpu();
 217 cpu_softc_t *sc = device_private(ci->ci_dev);
185 218
186#ifdef CPU_DEBUG 219#ifdef CPU_DEBUG
187 thunk_printf_debug("cpu_switchto [%s,pid=%d,lid=%d] -> [%s,pid=%d,lid=%d]\n", 220 thunk_printf_debug("cpu_switchto [%s,pid=%d,lid=%d] -> [%s,pid=%d,lid=%d]\n",
188 oldlwp ? oldlwp->l_name : "none", 221 oldlwp ? oldlwp->l_name : "none",
189 oldlwp ? oldlwp->l_proc->p_pid : -1, 222 oldlwp ? oldlwp->l_proc->p_pid : -1,
190 oldlwp ? oldlwp->l_lid : -1, 223 oldlwp ? oldlwp->l_lid : -1,
191 newlwp ? newlwp->l_name : "none", 224 newlwp ? newlwp->l_name : "none",
192 newlwp ? newlwp->l_proc->p_pid : -1, 225 newlwp ? newlwp->l_proc->p_pid : -1,
193 newlwp ? newlwp->l_lid : -1); 226 newlwp ? newlwp->l_lid : -1);
194 if (oldpcb) { 227 if (oldpcb) {
195 thunk_printf_debug(" oldpcb uc_link=%p, uc_stack.ss_sp=%p, " 228 thunk_printf_debug(" oldpcb uc_link=%p, uc_stack.ss_sp=%p, "
196 "uc_stack.ss_size=%d\n", 229 "uc_stack.ss_size=%d\n",
197 oldpcb->pcb_ucp.uc_link, 230 oldpcb->pcb_ucp.uc_link,
198 oldpcb->pcb_ucp.uc_stack.ss_sp, 231 oldpcb->pcb_ucp.uc_stack.ss_sp,
199 (int)oldpcb->pcb_ucp.uc_stack.ss_size); 232 (int)oldpcb->pcb_ucp.uc_stack.ss_size);
200 } 233 }
201 if (newpcb) { 234 if (newpcb) {
202 thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, " 235 thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, "
203 "uc_stack.ss_size=%d\n", 236 "uc_stack.ss_size=%d\n",
204 newpcb->pcb_ucp.uc_link, 237 newpcb->pcb_ucp.uc_link,
205 newpcb->pcb_ucp.uc_stack.ss_sp, 238 newpcb->pcb_ucp.uc_stack.ss_sp,
206 (int)newpcb->pcb_ucp.uc_stack.ss_size); 239 (int)newpcb->pcb_ucp.uc_stack.ss_size);
207 } 240 }
208#endif /* !CPU_DEBUG */ 241#endif /* !CPU_DEBUG */
209 242
210 ci->ci_stash = oldlwp; 243 /* create atomic switcher */
211 244 thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic,
212 if (oldpcb) { 245 2, oldlwp, newlwp, NULL);
213 oldpcb->pcb_errno = thunk_geterrno(); 246
214 thunk_seterrno(newpcb->pcb_errno); 247 if (!oldpcb) {
215 curlwp = newlwp; 248 thunk_setcontext(&sc->sc_ucp);
216 if (thunk_swapcontext(&oldpcb->pcb_ucp, &newpcb->pcb_ucp)) 249 /* never returns */
217 panic("swapcontext failed"); 
218 } else { 250 } else {
219 thunk_seterrno(newpcb->pcb_errno); 251 thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp);
220 curlwp = newlwp; 252 /* returns here */
221 if (thunk_setcontext(&newpcb->pcb_ucp)) 
222 panic("setcontext failed"); 
223 } 253 }
224 254
225#ifdef CPU_DEBUG 255#ifdef CPU_DEBUG
226 thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp); 256 thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp);
227#endif 257#endif
228 return ci->ci_stash; 258 return ci->ci_stash;
229} 259}
230 260
231void 261void
232cpu_dumpconf(void) 262cpu_dumpconf(void)
233{ 263{
234#ifdef CPU_DEBUG 264#ifdef CPU_DEBUG
235 thunk_printf_debug("cpu_dumpconf\n"); 265 thunk_printf_debug("cpu_dumpconf\n");
236#endif 266#endif
237} 267}
238 268
239void 269void
240cpu_signotify(struct lwp *l) 270cpu_signotify(struct lwp *l)
241{ 271{
242} 272}
243 273
244void 274void
245cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) 275cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags)
246{ 276{
247 struct pcb *pcb = lwp_getpcb(l); 277 struct pcb *pcb = lwp_getpcb(l);
248 ucontext_t *ucp = &pcb->pcb_userret_ucp; 278 ucontext_t *ucp = &pcb->pcb_userret_ucp;
249  279
250#ifdef CPU_DEBUG 280#ifdef CPU_DEBUG
251 thunk_printf_debug("cpu_getmcontext\n"); 281 thunk_printf_debug("cpu_getmcontext\n");
252#endif 282#endif
253 memcpy(mcp, &ucp->uc_mcontext, sizeof(mcontext_t)); 283 memcpy(mcp, &ucp->uc_mcontext, sizeof(mcontext_t));
254 return; 284 return;
255} 285}
256 286
257int 287int
258cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) 288cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags)
259{ 289{
260 struct pcb *pcb = lwp_getpcb(l); 290 struct pcb *pcb = lwp_getpcb(l);
261 ucontext_t *ucp = &pcb->pcb_userret_ucp; 291 ucontext_t *ucp = &pcb->pcb_userret_ucp;
262 292
263#ifdef CPU_DEBUG 293#ifdef CPU_DEBUG
264 thunk_printf_debug("cpu_setmcontext\n"); 294 thunk_printf_debug("cpu_setmcontext\n");
265#endif 295#endif
266 memcpy(&ucp->uc_mcontext, mcp, sizeof(mcontext_t)); 296 memcpy(&ucp->uc_mcontext, mcp, sizeof(mcontext_t));
267 return 0; 297 return 0;
268} 298}
269 299
270void 300void
271cpu_idle(void) 301cpu_idle(void)
272{ 302{
273 struct cpu_info *ci = curcpu(); 303 struct cpu_info *ci = curcpu();
274 304
275 if (ci->ci_want_resched) 305 if (ci->ci_want_resched)
276 return; 306 return;
277 307
278 thunk_idle(); 308 thunk_idle();
279} 309}
280 310
281void 311void
282cpu_lwp_free(struct lwp *l, int proc) 312cpu_lwp_free(struct lwp *l, int proc)
283{ 313{
284#ifdef CPU_DEBUG 314#ifdef CPU_DEBUG
285 thunk_printf_debug("cpu_lwp_free (dummy)\n"); 315 thunk_printf_debug("cpu_lwp_free (dummy)\n");
286#endif 316#endif
287} 317}
288 318
289void 319void
290cpu_lwp_free2(struct lwp *l) 320cpu_lwp_free2(struct lwp *l)
291{ 321{
292 struct pcb *pcb = lwp_getpcb(l); 322 struct pcb *pcb = lwp_getpcb(l);
293 323
294#ifdef CPU_DEBUG 324#ifdef CPU_DEBUG
295 thunk_printf_debug("cpu_lwp_free2\n"); 325 thunk_printf_debug("cpu_lwp_free2\n");
296#endif 326#endif
297 327
298 if (pcb == NULL) 328 if (pcb == NULL)
299 return; 329 return;
300 /* XXX nothing to do? */ 330 /* XXX nothing to do? */
301} 331}
302 332
303static void 333static void
304cpu_lwp_trampoline(ucontext_t *ucp, void (*func)(void *), void *arg) 334cpu_lwp_trampoline(ucontext_t *ucp, void (*func)(void *), void *arg)
305{ 335{
306#ifdef CPU_DEBUG 336#ifdef CPU_DEBUG
307 thunk_printf_debug("cpu_lwp_trampoline called with func %p, arg %p\n", (void *) func, arg); 337 thunk_printf_debug("cpu_lwp_trampoline called with func %p, arg %p\n", (void *) func, arg);
308#endif 338#endif
309 /* init lwp */ 339 /* init lwp */
310 lwp_startup(curcpu()->ci_stash, curlwp); 340 lwp_startup(curcpu()->ci_stash, curlwp);
311 341
312 /* actual jump */ 342 /* actual jump */
313 thunk_makecontext(ucp, (void (*)(void)) func, 1, arg, NULL, NULL); 343 thunk_makecontext(ucp, (void (*)(void)) func, 1, arg, NULL, NULL);
314 thunk_setcontext(ucp); 344 thunk_setcontext(ucp);
315} 345}
316 346
317void 347void
318cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize, 348cpu_lwp_fork(struct lwp *l1, struct lwp *l2, void *stack, size_t stacksize,
319 void (*func)(void *), void *arg) 349 void (*func)(void *), void *arg)
320{ 350{
321 struct pcb *pcb1 = lwp_getpcb(l1); 351 struct pcb *pcb1 = lwp_getpcb(l1);
322 struct pcb *pcb2 = lwp_getpcb(l2); 352 struct pcb *pcb2 = lwp_getpcb(l2);
323 353
324#ifdef CPU_DEBUG 354#ifdef CPU_DEBUG
325 thunk_printf_debug("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n", 355 thunk_printf_debug("cpu_lwp_fork [%s/%p] -> [%s/%p] stack=%p stacksize=%d\n",
326 l1 ? l1->l_name : "none", l1, 356 l1 ? l1->l_name : "none", l1,
327 l2 ? l2->l_name : "none", l2, 357 l2 ? l2->l_name : "none", l2,
328 stack, (int)stacksize); 358 stack, (int)stacksize);
329#endif 359#endif
330 360
331 if (stack) 361 if (stack)
332 panic("%s: stack passed, can't handle\n", __func__); 362 panic("%s: stack passed, can't handle\n", __func__);
333 363
334 /* copy the PCB and its switchframes from parent */ 364 /* copy the PCB and its switchframes from parent */
335 memcpy(pcb2, pcb1, sizeof(struct pcb)); 365 memcpy(pcb2, pcb1, sizeof(struct pcb));
336 366
337 /* refresh context */ 367 /* refresh context */
338 if (thunk_getcontext(&pcb2->pcb_ucp)) 368 if (thunk_getcontext(&pcb2->pcb_ucp))
339 panic("getcontext failed"); 369 panic("getcontext failed");
340 370
341 /* recalculate the system stack top */ 371 /* recalculate the system stack top */
342 pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE; 372 pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE;
343 373
344 /* get l2 its own stack */ 374 /* get l2 its own stack */
345 pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack; 375 pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack;
346 pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack; 376 pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack;
347 pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; 377 pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
348 pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp; 378 pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp;
349 thunk_makecontext(&pcb2->pcb_ucp, 379 thunk_makecontext(&pcb2->pcb_ucp,
350 (void (*)(void)) cpu_lwp_trampoline, 380 (void (*)(void)) cpu_lwp_trampoline,
351 3, &pcb2->pcb_ucp, func, arg); 381 3, &pcb2->pcb_ucp, func, arg);
352} 382}
353 383
354void 384void
355cpu_initclocks(void) 385cpu_initclocks(void)
356{ 386{
357 extern timer_t clock_timerid; 387 extern timer_t clock_timerid;
358 388
359 thunk_timer_start(clock_timerid, HZ); 389 thunk_timer_start(clock_timerid, HZ);
360} 390}
361 391
362void 392void
363cpu_startup(void) 393cpu_startup(void)
364{ 394{
365 vaddr_t minaddr, maxaddr; 395 vaddr_t minaddr, maxaddr;
366 size_t msgbufsize = 32 * 1024; 396 size_t msgbufsize = 32 * 1024;
367 397
368 /* get ourself a message buffer */ 398 /* get ourself a message buffer */
369 um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP); 399 um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP);
370 if (um_msgbuf == NULL) 400 if (um_msgbuf == NULL)
371 panic("couldn't allocate msgbuf"); 401 panic("couldn't allocate msgbuf");
372 initmsgbuf(um_msgbuf, msgbufsize); 402 initmsgbuf(um_msgbuf, msgbufsize);
373 403
374 /* allocate a submap for physio, 1Mb enough? */ 404 /* allocate a submap for physio, 1Mb enough? */
375 minaddr = 0; 405 minaddr = 0;
376 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 406 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
377 1024 * 1024, 0, false, NULL); 407 1024 * 1024, 0, false, NULL);
378 408
379 /* say hi! */ 409 /* say hi! */
380 banner(); 410 banner();
381 411
382 /* init lwp0 */ 412 /* init lwp0 */
383 memset(&lwp0pcb, 0, sizeof(lwp0pcb)); 413 memset(&lwp0pcb, 0, sizeof(lwp0pcb));
384 thunk_getcontext(&lwp0pcb.pcb_ucp); 414 thunk_getcontext(&lwp0pcb.pcb_ucp);
 415 lwp0pcb.pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK;
385 uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb); 416 uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb);
386 memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t)); 417 memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t));
387 418
388 /* set stack top */ 419 /* set stack top */
389 lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE; 420 lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE;
390} 421}
391 422
392void 423void
393cpu_rootconf(void) 424cpu_rootconf(void)
394{ 425{
395 extern char *usermode_root_device; 426 extern char *usermode_root_device;
396 device_t rdev; 427 device_t rdev;
397 428
398 if (usermode_root_device != NULL) { 429 if (usermode_root_device != NULL) {
399 rdev = device_find_by_xname(usermode_root_device); 430 rdev = device_find_by_xname(usermode_root_device);
400 } else { 431 } else {
401 rdev = device_find_by_xname("ld0"); 432 rdev = device_find_by_xname("ld0");
402 if (rdev == NULL) 433 if (rdev == NULL)
403 rdev = device_find_by_xname("md0"); 434 rdev = device_find_by_xname("md0");
404 } 435 }
405 436
406 aprint_normal("boot device: %s\n", 437 aprint_normal("boot device: %s\n",
407 rdev ? device_xname(rdev) : "<unknown>"); 438 rdev ? device_xname(rdev) : "<unknown>");
408 setroot(rdev, 0); 439 setroot(rdev, 0);
409} 440}
410 441
411bool 442bool
412cpu_intr_p(void) 443cpu_intr_p(void)
413{ 444{
414 int idepth; 445 int idepth;
415 446
416 kpreempt_disable(); 447 kpreempt_disable();
417 idepth = curcpu()->ci_idepth; 448 idepth = curcpu()->ci_idepth;
418 kpreempt_enable(); 449 kpreempt_enable();
419 450
420 return (idepth >= 0); 451 return (idepth >= 0);
421} 452}